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"
26#include "llvm/Support/Debug.h"
28#include <optional>
29
30#define DEBUG_TYPE "rematerializer"
31
32using namespace llvm;
34
35// Pin the vtable to this file.
36void Rematerializer::Listener::anchor() {}
37
38/// Checks whether the value in \p LI at \p UseIdx is identical to \p OVNI (this
39/// implies it is also live there). When \p LI has sub-ranges, checks that
40/// all sub-ranges intersecting with \p Mask are also live at \p UseIdx.
41static bool isIdenticalAtUse(const VNInfo &OVNI, LaneBitmask Mask,
42 SlotIndex UseIdx, const LiveInterval &LI) {
43 if (&OVNI != LI.getVNInfoAt(UseIdx))
44 return false;
45
46 if (LI.hasSubRanges()) {
47 // Check that intersecting subranges are live at user.
48 for (const LiveInterval::SubRange &SR : LI.subranges()) {
49 if ((SR.LaneMask & Mask).none())
50 continue;
51 if (!SR.liveAt(UseIdx))
52 return false;
53
54 // Early exit if all used lanes are checked. No need to continue.
55 Mask &= ~SR.LaneMask;
56 if (Mask.none())
57 break;
58 }
59 }
60 return true;
61}
62
63/// If \p MO is a virtual read register, returns it. Otherwise returns the
64/// sentinel register.
66 if (!MO.isReg() || !MO.readsReg())
67 return Register();
68 Register Reg = MO.getReg();
69 if (Reg.isPhysical()) {
70 // By the requirements on trivially rematerializable instructions, a
71 // physical register use is either constant or ignorable.
72 return Register();
73 }
74 return Reg;
75}
76
78 unsigned UseRegion,
80 MachineInstr *FirstMI =
81 getReg(RootIdx).getRegionUseBounds(UseRegion, LIS).first;
82 // If there are no users in the region, rematerialize the register at the very
83 // end of the region.
85 FirstMI ? FirstMI : Regions[UseRegion].second;
86 RegisterIdx NewRegIdx =
87 rematerializeToPos(RootIdx, UseRegion, InsertPos, DRI);
88 transferRegionUsers(RootIdx, NewRegIdx, UseRegion);
89 return NewRegIdx;
90}
91
96 assert(!DRI.DependencyMap.contains(RootIdx));
97 LLVM_DEBUG(dbgs() << "Rematerializing " << printID(RootIdx) << '\n');
98
100 // Copy all dependencies because recursive rematerialization of dependencies
101 // may invalidate references to the backing vector of registers.
102 SmallVector<RegisterIdx, 2> OldDeps(getReg(RootIdx).Dependencies);
103 for (RegisterIdx DepRegIdx : OldDeps) {
104 // Recursively rematerialize required dependencies at the same position as
105 // the root. Registers form a DAG so the recursion is guaranteed to
106 // terminate.
107 auto RematIdx = DRI.DependencyMap.find(DepRegIdx);
108 RegisterIdx NewDepRegIdx;
109 if (RematIdx == DRI.DependencyMap.end())
110 NewDepRegIdx = rematerializeToPos(DepRegIdx, UseRegion, InsertPos, DRI);
111 else
112 NewDepRegIdx = RematIdx->second;
113 NewDeps.push_back(NewDepRegIdx);
114 }
115 RegisterIdx NewIdx =
116 rematerializeReg(RootIdx, UseRegion, InsertPos, std::move(NewDeps));
117 DRI.DependencyMap.insert({RootIdx, NewIdx});
118 return NewIdx;
119}
120
122 unsigned UserRegion, MachineInstr &UserMI) {
123 transferUserImpl(FromRegIdx, ToRegIdx, UserMI);
124
125 Regs[ToRegIdx].addUser(&UserMI, UserRegion);
126 extendToNewUsers(ToRegIdx, &UserMI);
127
128 Regs[FromRegIdx].eraseUser(&UserMI, UserRegion);
129 shrinkToUses(FromRegIdx);
130}
131
133 RegisterIdx ToRegIdx,
134 unsigned UseRegion) {
135 Reg &FromReg = Regs[FromRegIdx];
136 auto UsesIt = FromReg.Uses.find(UseRegion);
137 if (UsesIt == FromReg.Uses.end())
138 return;
139
140 const SmallDenseSet<MachineInstr *, 4> &RegionUsers = UsesIt->getSecond();
142 for (MachineInstr *UserMI : RegionUsers) {
143 transferUserImpl(FromRegIdx, ToRegIdx, *UserMI);
144 NewUsers.push_back(UserMI);
145 }
146
147 extendToNewUsers(ToRegIdx, NewUsers);
148 Regs[ToRegIdx].addUsers(RegionUsers, UseRegion);
149
150 FromReg.Uses.erase(UseRegion);
151 shrinkToUses(FromRegIdx);
152}
153
155 RegisterIdx ToRegIdx) {
156 Reg &FromReg = Regs[FromRegIdx];
158 for (const auto &[UseRegion, RegionUsers] : FromReg.Uses) {
159 for (MachineInstr *UserMI : RegionUsers) {
160 transferUserImpl(FromRegIdx, ToRegIdx, *UserMI);
161 NewUsers.push_back(UserMI);
162 }
163 Regs[ToRegIdx].addUsers(RegionUsers, UseRegion);
164 }
165 extendToNewUsers(ToRegIdx, NewUsers);
166
167 FromReg.Uses.clear();
168 deleteReg(FromRegIdx);
169}
170
171void Rematerializer::transferUserImpl(RegisterIdx FromRegIdx,
172 RegisterIdx ToRegIdx,
173 MachineInstr &UserMI) {
174 assert(FromRegIdx != ToRegIdx && "identical registers");
175 assert(getOriginOrSelf(FromRegIdx) == getOriginOrSelf(ToRegIdx) &&
176 "unrelated registers");
177
178 LLVM_DEBUG(dbgs() << "User transfer from " << printID(FromRegIdx) << " to "
179 << printID(ToRegIdx) << ": " << printUser(&UserMI) << '\n');
180
181 UserMI.substituteRegister(getReg(FromRegIdx).getDefReg(),
182 getReg(ToRegIdx).getDefReg(), 0, TRI);
183
184 // If the user is rematerializable, we must change its dependency to the
185 // new register.
186 if (RegisterIdx UserRegIdx = getDefRegIdx(UserMI); UserRegIdx != NoReg) {
187 // Look for the user's dependency that matches the register.
188 for (RegisterIdx &DepRegIdx : Regs[UserRegIdx].Dependencies) {
189 if (DepRegIdx == FromRegIdx) {
190 DepRegIdx = ToRegIdx;
191 return;
192 }
193 }
194 llvm_unreachable("broken dependency");
195 }
196}
197
200 unsigned SubIdx = MO.getSubReg();
201 LaneBitmask Mask = SubIdx ? TRI.getSubRegIndexLaneMask(SubIdx)
202 : MRI.getMaxLaneMaskForVReg(MO.getReg());
204 MO.getReg(), Mask,
205 LIS.getInstructionIndex(*MO.getParent()).getRegSlot(true), Uses);
206}
207
209 SlotIndex RefSlot,
211 if (Uses.empty())
212 return true;
213 const LiveInterval &LI = LIS.getInterval(Reg);
214 const VNInfo *DefVN = LI.getVNInfoAt(RefSlot);
215 for (SlotIndex Use : Uses) {
216 if (!isIdenticalAtUse(*DefVN, Mask, Use, LI))
217 return false;
218 }
219 return true;
220}
221
223 unsigned Region,
224 SlotIndex Before) const {
225 auto It = Rematerializations.find(getOriginOrSelf(RegIdx));
226 if (It == Rematerializations.end())
227 return NoReg;
228 const RematsOf &Remats = It->getSecond();
229
230 SlotIndex BestSlot;
231 RegisterIdx BestRegIdx = NoReg;
232 for (RegisterIdx RematRegIdx : Remats) {
233 const Reg &RematReg = getReg(RematRegIdx);
234 if (RematReg.DefRegion != Region || RematReg.Uses.empty())
235 continue;
236 SlotIndex RematRegSlot =
237 LIS.getInstructionIndex(*RematReg.DefMI).getRegSlot();
238 if (RematRegSlot < Before &&
239 (BestRegIdx == NoReg || RematRegSlot > BestSlot)) {
240 BestSlot = RematRegSlot;
241 BestRegIdx = RematRegIdx;
242 }
243 }
244 return BestRegIdx;
245}
246
247void Rematerializer::deleteReg(RegisterIdx RootIdx) {
248 assert(getReg(RootIdx).Uses.empty() && "register still has uses");
249
250 // Traverse the root's dependency DAG depth-first to find the set of registers
251 // we can delete and a legal order to delete them in.
252 SmallVector<RegisterIdx, 4> DepDAG{RootIdx};
253 SmallVector<RegisterIdx, 8> DeleteOrder{RootIdx};
254 do {
255 // A deleted register's dependencies may be deletable too.
256 const Reg &DeleteReg = getReg(DepDAG.pop_back_val());
257 for (RegisterIdx DepRegIdx : DeleteReg.Dependencies) {
258 // All dependencies lose a user (the deleted register).
259 Reg &DepReg = Regs[DepRegIdx];
260 DepReg.eraseUser(DeleteReg.DefMI, DeleteReg.DefRegion);
261 if (DepReg.Uses.empty()) {
262 DeleteOrder.push_back(DepRegIdx);
263 DepDAG.push_back(DepRegIdx);
264 }
265 }
266 } while (!DepDAG.empty());
267
268 for (RegisterIdx RegIdx : DeleteOrder) {
269 preDeletion(RegIdx);
270 Reg &DeleteReg = Regs[RegIdx];
271 Register DefReg = DeleteReg.getDefReg();
272 LIS.RemoveMachineInstrFromMaps(*DeleteReg.DefMI);
273 DeleteReg.DefMI->eraseFromParent();
274 DeleteReg.DefMI = nullptr;
275 LIS.removeInterval(DefReg);
276 }
277
278 SmallSet<RegisterIdx, 8> ShrinkRematRegs;
279 SmallSet<Register, 8> ShrinkUnrematRegs;
280
281 // All dependencies lose a user; their live interval could be shrunk.
282 for (RegisterIdx DeletedRegIdx : DeleteOrder) {
283 for (RegisterIdx DepRegIdx : getReg(DeletedRegIdx).Dependencies) {
284 const Reg &DepReg = getReg(DepRegIdx);
285 if (DepReg.isAlive() && ShrinkRematRegs.insert(DepRegIdx).second) {
286 assert(!DepReg.Uses.empty() && "dep should have uses");
287 shrinkToUses(DepRegIdx);
288 }
289 }
290 for (const auto [Reg, Mask] : getUnrematableDeps(DeletedRegIdx)) {
291 if (ShrinkUnrematRegs.insert(Reg).second)
292 shrinkToUsesUnremat(Reg);
293 }
294 }
295}
296
297void Rematerializer::DeadDefDelegate::LRE_WillEraseInstruction(
298 MachineInstr *MI) {
299 RegisterIdx RegIdx = Remater.getDefRegIdx(*MI);
300 if (RegIdx == Rematerializer::NoReg) {
301 // This is an unrematerializable register.
302 Remater.noteMIWillBeDeleted(*MI);
303 LLVM_DEBUG(dbgs() << "** About to delete dead definition: " << *MI);
304
305 // Do a linear scan through regions to figure out which one the about to be
306 // deleted unrematerializable MI is a part of. This is expensive but should
307 // happen extremely rarely.
308 //
309 // FIXME: the rematerializer should stop tracking regions and operate on a
310 // machine basic block-basis. This would simplify this and a lot of the
311 // tracking elsewhere.
312 MachineBasicBlock::iterator It = MI->getIterator();
313 const LiveIntervals &LIS = Remater.LIS;
314 SlotIndex MISlot = LIS.getInstructionIndex(*MI);
315 unsigned MIRegion = ~0U;
316 for (auto [RegionIdx, Bounds] : enumerate(Remater.Regions)) {
317 auto &[RegionBegin, RegionEnd] = Bounds;
319 skipDebugInstructionsForward(RegionBegin, RegionEnd);
320 if (FirstMI == RegionEnd) {
321 // The MI cannot be in an empty region.
322 continue;
323 }
324
325 if (LIS.getInstructionIndex(*FirstMI) <= MISlot) {
326 // FistMI exists inside the region so this is guaranteed to point to a
327 // non-debug MI.
329 skipDebugInstructionsBackward(std::prev(RegionEnd), RegionBegin);
330 if (LIS.getInstructionIndex(*LastMI) < MISlot)
331 continue;
332
333 // We have found the region the MI is a part of.
334 MIRegion = RegionIdx;
335 if (RegionBegin == It)
336 ++RegionBegin;
337 break;
338 }
339 }
340
341 // All rematerializable registers that this MI uses must be notified.
342 SmallDenseSet<Register, 2> UsedRegs;
343 for (const MachineOperand &MO : MI->all_uses()) {
344 Register Reg = MO.getReg();
345 if (Reg.isVirtual() && !UsedRegs.insert(Reg).second)
346 continue;
347 auto RematRegUse = Remater.RegToIdx.find(Reg);
348 if (RematRegUse == Remater.RegToIdx.end())
349 continue;
350 assert(MIRegion != ~0U && "remat user cannot be outside regions");
351 Remater.Regs[RematRegUse->second].eraseUser(MI, MIRegion);
352 }
353 return;
354 }
355 // This is a rematerializable register.
356
357 // All rematerializable dependencies must be notified.
358 Reg &DeleteReg = Remater.Regs[RegIdx];
359 for (RegisterIdx DepRegIdx : DeleteReg.Dependencies)
360 Remater.Regs[DepRegIdx].eraseUser(MI, DeleteReg.DefRegion);
361
362 assert(DeleteReg.isAlive() && "register must be alive");
363 assert(DeleteReg.Uses.empty() && "register should no longer have uses");
364
365 // The live-range editor will delete the defining instruction from the MIR
366 // as well as the register's live-range, so we just need to nullify the def
367 // internally.
368 Remater.preDeletion(RegIdx);
369 DeleteReg.DefMI = nullptr;
370}
371
372void Rematerializer::preDeletion(RegisterIdx DeleteRegIdx) {
373 Reg &DeleteReg = Regs[DeleteRegIdx];
374 assert(DeleteReg.isAlive() && "register must still be alive");
375 noteRegWillBeDeleted(DeleteRegIdx);
376 LLVM_DEBUG(dbgs() << "** About to delete " << printID(DeleteRegIdx) << "\n");
377
378 // Update region boundary if necessary. It is not possible for the deleted
379 // instruction to be the upper region boundary since we don't ever consider
380 // them rematerializable.
381 MachineBasicBlock::iterator &RegionBegin = Regions[DeleteReg.DefRegion].first;
382 if (RegionBegin == DeleteReg.DefMI)
383 ++RegionBegin;
384
385 if (isOriginalRegister(DeleteRegIdx))
386 return;
387
388 // Delete rematerialized register from its origin's rematerializations.
389 const RegisterIdx OriginIdx = getOriginOf(DeleteRegIdx);
390 RematsOf &OriginRemats = Rematerializations.at(OriginIdx);
391 assert(OriginRemats.contains(DeleteRegIdx) && "broken remat<->origin link");
392 OriginRemats.erase(DeleteRegIdx);
393 if (OriginRemats.empty())
394 Rematerializations.erase(OriginIdx);
395}
396
399 LiveIntervals &LIS)
400 : Regions(Regions), MRI(MF.getRegInfo()), LIS(LIS),
401 TII(*MF.getSubtarget().getInstrInfo()), TRI(TII.getRegisterInfo()) {
402#ifdef EXPENSIVE_CHECKS
403 // Check that regions are valid.
405 for (const auto &[RegionBegin, RegionEnd] : Regions) {
406 assert(RegionBegin != RegionEnd && "empty region");
407 for (auto MI = RegionBegin; MI != RegionEnd; ++MI) {
408 bool IsNewMI = SeenMIs.insert(&*MI).second;
409 assert(IsNewMI && "overlapping regions");
410 assert(!MI->isTerminator() && "terminator in region");
411 }
412 if (RegionEnd != RegionBegin->getParent()->end()) {
413 bool IsNewMI = SeenMIs.insert(&*RegionEnd).second;
414 assert(IsNewMI && "overlapping regions (upper bound)");
415 }
416 }
417#endif
418}
419
421 Regs.clear();
422 UnrematableDeps.clear();
423 Origins.clear();
424 Rematerializations.clear();
425 RegionMBB.clear();
426 RegToIdx.clear();
427 if (Regions.empty())
428 return false;
429
430 /// Maps all MIs to their parent region. Region terminators are considered
431 /// part of the region they terminate.
433
434 // Initialize MI to containing region mapping.
435 RegionMBB.reserve(Regions.size());
436 for (unsigned I = 0, E = Regions.size(); I < E; ++I) {
437 RegionBoundaries Region = Regions[I];
438 assert(Region.first != Region.second && "empty cannot be region");
439 for (auto MI = Region.first; MI != Region.second; ++MI) {
440 assert(!MIRegion.contains(&*MI) && "regions should not intersect");
441 MIRegion.insert({&*MI, I});
442 }
444 RegionMBB.push_back(&MBB);
445
446 // A terminator instruction is considered part of the region it terminates.
447 if (Region.second != MBB.end()) {
448 MachineInstr *RegionTerm = &*Region.second;
449 assert(!MIRegion.contains(RegionTerm) && "regions should not intersect");
450 MIRegion.insert({RegionTerm, I});
451 }
452 }
453
454 const unsigned NumVirtRegs = MRI.getNumVirtRegs();
455 BitVector SeenRegs(NumVirtRegs);
456 for (unsigned I = 0, E = NumVirtRegs; I != E; ++I) {
457 if (!SeenRegs[I])
458 addRegIfRematerializable(I, MIRegion, SeenRegs);
459 }
460 assert(Regs.size() == UnrematableDeps.size());
461
462 LLVM_DEBUG({
463 for (RegisterIdx I = 0, E = getNumRegs(); I < E; ++I)
464 dbgs() << printDependencyDAG(I) << '\n';
465 });
466 return !Regs.empty();
467}
468
469void Rematerializer::addRegIfRematerializable(
470 unsigned VirtRegIdx, const DenseMap<MachineInstr *, unsigned> &MIRegion,
471 BitVector &SeenRegs) {
472 assert(!SeenRegs[VirtRegIdx] && "register already seen");
473 Register DefReg = Register::index2VirtReg(VirtRegIdx);
474 SeenRegs.set(VirtRegIdx);
475
476 MachineOperand *MO = MRI.getOneDef(DefReg);
477 if (!MO)
478 return;
479 MachineInstr &DefMI = *MO->getParent();
480 if (!isMIRematerializable(DefMI))
481 return;
482 auto DefRegion = MIRegion.find(&DefMI);
483 if (DefRegion == MIRegion.end())
484 return;
485
486 Reg RematReg;
487 RematReg.DefMI = &DefMI;
488 RematReg.DefRegion = DefRegion->second;
489 unsigned SubIdx = DefMI.getOperand(0).getSubReg();
490 RematReg.Mask = SubIdx ? TRI.getSubRegIndexLaneMask(SubIdx)
491 : MRI.getMaxLaneMaskForVReg(DefReg);
492
493 // Collect the candidate's direct users, both rematerializable and
494 // unrematerializable. MIs outside provided regions cannot be tracked so the
495 // registers they use are not safely rematerializable.
496 for (MachineInstr &UseMI : MRI.use_nodbg_instructions(DefReg)) {
497 if (auto UseRegion = MIRegion.find(&UseMI); UseRegion != MIRegion.end())
498 RematReg.addUser(&UseMI, UseRegion->second);
499 else
500 return;
501 }
502 if (RematReg.Uses.empty())
503 return;
504
505 // Collect the candidate's dependencies, rematerializable or not. If the same
506 // rematerializable register is used multiple times we just need to consider
507 // it once.
510 for (const MachineOperand &MO : DefMI.all_uses()) {
511 Register DepReg = getRegDependency(MO);
512 if (!DepReg)
513 continue;
514 unsigned DepRegIdx = DepReg.virtRegIndex();
515 if (!SeenRegs[DepRegIdx])
516 addRegIfRematerializable(DepRegIdx, MIRegion, SeenRegs);
517 if (auto DepIt = RegToIdx.find(DepReg); DepIt != RegToIdx.end()) {
518 RematDeps.insert(DepIt->second);
519 } else {
520 LaneBitmask &CurrentMask =
521 UnrematDeps.try_emplace(DepReg, LaneBitmask::getNone()).first->second;
522 LaneBitmask Mask = MO.getSubReg()
523 ? TRI.getSubRegIndexLaneMask(MO.getSubReg())
524 : MRI.getMaxLaneMaskForVReg(DepReg);
525 CurrentMask |= Mask;
526 }
527 }
528
529 // The register is rematerializable.
530 RematReg.Dependencies = RematDeps.takeVector();
531 RegToIdx.insert({DefReg, Regs.size()});
532 Regs.push_back(RematReg);
533 UnrematableDeps.push_back(UnrematDeps.takeVector());
534}
535
536bool Rematerializer::isMIRematerializable(const MachineInstr &MI) const {
537 if (!TII.isReMaterializable(MI))
538 return false;
539
540 assert(MI.getOperand(0).getReg().isVirtual() && "should be virtual");
541 assert(MRI.hasOneDef(MI.getOperand(0).getReg()) && "should have single def");
542
543 for (const MachineOperand &MO : MI.all_uses()) {
544 // We can't remat physreg uses, unless it is a constant or an ignorable
545 // use (e.g. implicit exec use on VALU instructions)
546 if (MO.getReg().isPhysical()) {
547 if (MRI.isConstantPhysReg(MO.getReg()) || TII.isIgnorableUse(MO))
548 continue;
549 return false;
550 }
551 }
552
553 return true;
554}
555
557 if (!MI.getNumOperands() || !MI.getOperand(0).isReg() ||
558 MI.getOperand(0).readsReg())
559 return NoReg;
560 Register Reg = MI.getOperand(0).getReg();
561 auto UserRegIt = RegToIdx.find(Reg);
562 if (UserRegIt == RegToIdx.end())
563 return NoReg;
564 return UserRegIt->second;
565}
566
570 SmallVectorImpl<RegisterIdx> &&Dependencies) {
571 RegisterIdx NewRegIdx = Regs.size();
572
573 Reg &NewReg = Regs.emplace_back();
574 Reg &FromReg = Regs[RegIdx];
575 NewReg.Mask = FromReg.Mask;
576 NewReg.DefRegion = UseRegion;
577 NewReg.Dependencies = std::move(Dependencies);
578
579 // Track rematerialization link between registers. Origins are always
580 // registers that existed originally, and rematerializations are always
581 // attached to them.
582 const RegisterIdx OriginIdx = getOriginOrSelf(RegIdx);
583 Origins.push_back(OriginIdx);
584 Rematerializations[OriginIdx].insert(NewRegIdx);
585
586 // Use the TII to rematerialize the defining instruction with a new defined
587 // register.
588 Register NewDefReg = MRI.cloneVirtualRegister(FromReg.getDefReg());
589 TII.reMaterialize(*RegionMBB[UseRegion], InsertPos, NewDefReg, 0,
590 *FromReg.DefMI);
591 NewReg.DefMI = &*std::prev(InsertPos);
592 RegToIdx.insert({NewDefReg, NewRegIdx});
593 postRematerialization(RegIdx, NewRegIdx);
594
595 noteRegCreated(NewRegIdx);
596 LLVM_DEBUG(dbgs() << "** Rematerialized " << printID(RegIdx) << " as "
597 << printRematReg(NewRegIdx) << '\n');
598 return NewRegIdx;
599}
600
603 Register DefReg) {
604 assert(RegToIdx.contains(DefReg) && "unknown defined register");
605 assert(RegToIdx.at(DefReg) == RegIdx && "incorrect defined register");
606 assert(!getReg(RegIdx).isAlive() && "register is still alive");
607
608 Reg &OriginReg = Regs[RegIdx];
609
610 // Re-establish the link between origin and rematerialization if necessary.
611 const bool RecreateOriginalReg = isOriginalRegister(RegIdx);
612 if (!RecreateOriginalReg)
613 Rematerializations[getOriginOf(RegIdx)].insert(RegIdx);
614
615 // Rematerialize from one of the existing rematerializations or from the
616 // origin. We expect at least one to exist, otherwise it would mean the value
617 // held by the original register is no longer available anywhere in the MF.
618 RegisterIdx ModelRegIdx;
619 if (RecreateOriginalReg) {
620 assert(Rematerializations.contains(RegIdx) && "expected remats");
621 ModelRegIdx = *Rematerializations.at(RegIdx).begin();
622 } else {
623 assert(getReg(getOriginOf(RegIdx)).isAlive() && "expected alive origin");
624 ModelRegIdx = getOriginOf(RegIdx);
625 }
626 const MachineInstr &ModelDefMI = *getReg(ModelRegIdx).DefMI;
627
628 TII.reMaterialize(*RegionMBB[OriginReg.DefRegion], InsertPos, DefReg, 0,
629 ModelDefMI);
630 OriginReg.DefMI = &*std::prev(InsertPos);
631 postRematerialization(ModelRegIdx, RegIdx);
632 LLVM_DEBUG(dbgs() << "** Recreated " << printID(RegIdx) << " as "
633 << printRematReg(RegIdx) << '\n');
634}
635
636void Rematerializer::postRematerialization(RegisterIdx ModelRegIdx,
637 RegisterIdx RematRegIdx) {
638 Reg &ModelReg = Regs[ModelRegIdx], &RematReg = Regs[RematRegIdx];
639
640 // The rematerialization has no user at this point so its interval will
641 // initially be empty.
642 SlotIndex UseIdx = LIS.InsertMachineInstrInMaps(*RematReg.DefMI).getRegSlot();
643 LIS.createAndComputeVirtRegInterval(RematReg.getDefReg());
644
645 // The start of the new register's region may have changed.
646 MachineBasicBlock::iterator &RegionBegin = Regions[RematReg.DefRegion].first;
647 if (RegionBegin == std::next(MachineBasicBlock::iterator(RematReg.DefMI)))
648 RegionBegin = RematReg.DefMI;
649
650 // Replace dependencies as needed in the rematerialized MI. All dependencies
651 // of the latter gain a new user.
652 auto ZipedDeps = zip_equal(ModelReg.Dependencies, RematReg.Dependencies);
653 for (const auto &[OldDepRegIdx, NewDepRegIdx] : ZipedDeps) {
654 LLVM_DEBUG(dbgs() << " Dependency: " << printID(OldDepRegIdx) << " -> "
655 << printID(NewDepRegIdx) << '\n');
656
657 Reg &NewDepReg = Regs[NewDepRegIdx];
658 if (OldDepRegIdx != NewDepRegIdx) {
659 Reg &OldDepReg = Regs[OldDepRegIdx];
660 RematReg.DefMI->substituteRegister(OldDepReg.getDefReg(),
661 NewDepReg.getDefReg(), 0, TRI);
662 }
663 NewDepReg.addUser(RematReg.DefMI, RematReg.DefRegion);
664 extendToNewUsers(NewDepRegIdx, RematReg.DefMI);
665 }
666
667 // Unrematerializable dependencies always gain a new user after a
668 // rematerialization; their live range may need to be extended.
669 for (const auto &[Reg, Mask] : getUnrematableDeps(ModelRegIdx))
670 extendInterval(LIS.getInterval(Reg), Mask, UseIdx);
671}
672
673void Rematerializer::extendToNewUsers(RegisterIdx RegIdx,
674 ArrayRef<MachineInstr *> NewUsers) const {
675 if (NewUsers.empty())
676 return;
677 const Reg &ExtendReg = getReg(RegIdx);
678 assert(ExtendReg.isAlive() && "register must be alive");
679
680 Register DefReg = ExtendReg.getDefReg();
681 LiveInterval &LI = LIS.getInterval(DefReg);
682 const LaneBitmask FullLaneMask = MRI.getMaxLaneMaskForVReg(DefReg);
683 const bool ShouldTrackSubReg = MRI.shouldTrackSubRegLiveness(DefReg);
684
685 // When subreg liveness tracking is required but no subrange exists yet (e.g.,
686 // the interval was computed with only a def of the entire register),
687 // initialize subranges from the main range before extending them. This must
688 // happen even if every new user reads the full mask, because other existing
689 // users of the register may read individual subregs and later passes
690 // (VirtRegRewriter) expect subranges to exist.
691 if (!LI.hasSubRanges() && ShouldTrackSubReg)
692 LI.createSubRangeFrom(LIS.getVNInfoAllocator(), FullLaneMask, LI);
693
694 // Extend all ranges in the register's live interval so that they reach the
695 // new users.
696 for (MachineInstr *UserMI : NewUsers) {
697 SlotIndex UseIdx = LIS.getInstructionIndex(*UserMI).getRegSlot();
698
699 // Derive register lanes read by that user.
700 LaneBitmask RegMask;
701 for (MachineOperand &MO : UserMI->all_uses()) {
702 if (MO.getReg() == DefReg) {
703 unsigned SubIdx = MO.getSubReg();
704 if (SubIdx == 0) {
705 RegMask = FullLaneMask;
706 break;
707 }
708 RegMask |= TRI.getSubRegIndexLaneMask(SubIdx);
709 }
710 }
711
712 if (RegMask != FullLaneMask) {
713 // Refine sub-ranges to be able to track the mask for that user.
715 LIS.getVNInfoAllocator(), RegMask, [](LiveInterval::SubRange &SR) {},
716 *LIS.getSlotIndexes(), TRI);
717 }
718 extendInterval(LI, RegMask, UseIdx);
719 }
720
721 LLVM_DEBUG({
722 if (ExtendReg.DefMI->getOperand(0).isDead())
723 dbgs() << "Clearing dead flag for "
724 << printRematReg(RegIdx, /*SkipRegions=*/false) << '\n';
725 });
726 ExtendReg.DefMI->getOperand(0).setIsDead(false);
727}
728
729void Rematerializer::extendInterval(LiveInterval &LI, LaneBitmask Mask,
730 SlotIndex UseIdx) const {
731 if (!LI.hasSubRanges()) {
732 if (!LI.liveAt(UseIdx))
733 LLVM_DEBUG(dbgs() << "Extending interval of register "
734 << printReg(LI.reg(), &TRI, 0, &MRI) << " to " << UseIdx
735 << '\n');
736 LIS.extendToIndices(LI, UseIdx);
737 return;
738 }
739
740 bool SubRangeExtended = false;
741 for (LiveInterval::SubRange &SR : LI.subranges()) {
742 if ((SR.LaneMask & Mask).any() && !SR.liveAt(UseIdx)) {
743 SubRangeExtended = true;
744 LLVM_DEBUG(dbgs() << "Extending subrange " << SR << " of register "
745 << printReg(LI.reg(), &TRI, 0, &MRI) << " to " << UseIdx
746 << '\n');
747 LIS.extendToIndices(SR, UseIdx);
748 }
749 }
750 if (!SubRangeExtended)
751 return;
752
753 // FIXME: this fully reconstructs the main live range from scratch, but
754 // there may be a more targeted way to make the update.
755 LI.clear();
756 LIS.constructMainRangeFromSubranges(LI);
757}
758
759void Rematerializer::shrinkToUses(RegisterIdx RegIdx) {
760 Reg &ShrinkReg = Regs[RegIdx];
761 assert(ShrinkReg.isAlive() && "register must be alive");
762 if (ShrinkReg.Uses.empty()) {
763 deleteReg(RegIdx);
764 return;
765 }
766
767 // By construction, registers should never end up with multiple disconnected
768 // components or dead definitions.
769 LiveInterval &LI = LIS.getInterval(ShrinkReg.getDefReg());
770 LLVM_DEBUG(dbgs() << "Shrinking interval of " << printID(RegIdx) << ": " << LI
771 << '\n');
772 LIS.shrinkToUses(&LI);
773}
774
775void Rematerializer::shrinkToUsesUnremat(Register Reg) {
776 LiveInterval &LI = LIS.getInterval(Reg);
777 LLVM_DEBUG(dbgs() << "Shrinking interval of unrematerializable register "
778 << LI << '\n');
779
780 SmallVector<MachineInstr *, 2> DeadDefs;
781 if (!LIS.shrinkToUses(&LI, &DeadDefs)) {
782 assert(DeadDefs.empty() && "expected no dead def");
783 return;
784 }
785
786 // This should be a very rare occurence, but shrinking an unrematerializable
787 // register could create dead defs.
788 if (DeadDefs.empty())
789 return;
790
791 // The live-range editor delegate will take care of reflecting the
792 // elimination of all dead definitions in the rematerializer.
794 DeadDefDelegate DeadDefDeleg(*this);
795 MachineFunction &MF = *DeadDefs.front()->getParent()->getParent();
796 LiveRangeEdit(nullptr, NewRegs, MF, LIS, nullptr, &DeadDefDeleg)
797 .eliminateDeadDefs(DeadDefs);
798}
799
800std::pair<MachineInstr *, MachineInstr *>
802 const LiveIntervals &LIS) const {
803 auto It = Uses.find(UseRegion);
804 if (It == Uses.end())
805 return {nullptr, nullptr};
806 const RegionUsers &RegionUsers = It->getSecond();
807 assert(!RegionUsers.empty() && "empty userset in region");
808
809 auto User = RegionUsers.begin(), UserEnd = RegionUsers.end();
810 MachineInstr *FirstMI = *User, *LastMI = FirstMI;
811 SlotIndex FirstIndex = LIS.getInstructionIndex(*FirstMI),
812 LastIndex = FirstIndex;
813
814 while (++User != UserEnd) {
815 SlotIndex UserIndex = LIS.getInstructionIndex(**User);
816 if (UserIndex < FirstIndex) {
817 FirstIndex = UserIndex;
818 FirstMI = *User;
819 } else if (UserIndex > LastIndex) {
820 LastIndex = UserIndex;
821 LastMI = *User;
822 }
823 }
824
825 return {FirstMI, LastMI};
826}
827
828void Rematerializer::Reg::addUser(MachineInstr *MI, unsigned Region) {
829 Uses[Region].insert(MI);
830}
831
832void Rematerializer::Reg::addUsers(const RegionUsers &NewUsers,
833 unsigned Region) {
834 Uses[Region].insert_range(NewUsers);
835}
836
837void Rematerializer::Reg::eraseUser(MachineInstr *MI, unsigned Region) {
838 RegionUsers &RUsers = Uses.at(Region);
839 assert(RUsers.contains(MI) && "user not in region");
840 if (RUsers.size() == 1)
841 Uses.erase(Region);
842 else
843 RUsers.erase(MI);
844}
845
847 return Printable([&, RootIdx](raw_ostream &OS) {
849 std::function<void(RegisterIdx, unsigned)> WalkTree =
850 [&](RegisterIdx RegIdx, unsigned Depth) -> void {
851 unsigned MaxDepth = std::max(RegDepths.lookup_or(RegIdx, Depth), Depth);
852 RegDepths.emplace_or_assign(RegIdx, MaxDepth);
853 for (RegisterIdx DepRegIdx : getReg(RegIdx).Dependencies)
854 WalkTree(DepRegIdx, Depth + 1);
855 };
856 WalkTree(RootIdx, 0);
857
858 // Sort in decreasing depth order to print root at the bottom.
860 RegDepths.end());
861 sort(Regs, [](const auto &LHS, const auto &RHS) {
862 return LHS.second > RHS.second;
863 });
864
865 OS << printID(RootIdx) << " has " << Regs.size() - 1 << " dependencies\n";
866 for (const auto &[RegIdx, Depth] : Regs) {
867 OS << indent(Depth, 2) << (Depth ? '|' : '*') << ' '
868 << printRematReg(RegIdx, /*SkipRegions=*/Depth) << '\n';
869 }
870 OS << printRegUsers(RootIdx);
871 });
872}
873
875 return Printable([&, RegIdx](raw_ostream &OS) {
876 const Reg &PrintReg = getReg(RegIdx);
877 OS << '(' << RegIdx << '/';
878 if (!PrintReg.isAlive()) {
879 OS << "<dead>";
880 } else {
881 OS << printReg(PrintReg.getDefReg(), &TRI,
882 PrintReg.DefMI->getOperand(0).getSubReg(), &MRI);
883 }
884 OS << ")[" << PrintReg.DefRegion << "]";
885 });
886}
887
889 bool SkipRegions) const {
890 return Printable([&, RegIdx, SkipRegions](raw_ostream &OS) {
891 const Reg &PrintReg = getReg(RegIdx);
892 OS << printID(RegIdx);
893 if (!SkipRegions) {
894 OS << " [" << PrintReg.DefRegion;
895 if (!PrintReg.Uses.empty()) {
896 assert(PrintReg.isAlive() && "dead register cannot have uses");
897 const LiveInterval &LI = LIS.getInterval(PrintReg.getDefReg());
898 // First display all regions in which the register is live-through and
899 // not used.
900 bool First = true;
901 for (const auto &[I, Bounds] : enumerate(Regions)) {
902 if (PrintReg.Uses.contains(I))
903 continue;
904 // The register must be live at the live-ins and live-outs of the
905 // region.
907 skipDebugInstructionsForward(Bounds.first, Bounds.second);
908 if (LiveIn == Bounds.second) {
909 // The region has no non-debug instructions, it's hard to assess
910 // whether the register is live across it without an index.
911 continue;
912 }
913 // LiveIn is inside the range and a non-debug instruction so we know
914 // this will also point to a non-debug instruction within the region.
916 std::prev(Bounds.second), Bounds.first);
917 if (LI.liveAt(LIS.getInstructionIndex(*LiveIn)) &&
918 LI.liveAt(LIS.getInstructionIndex(*LiveOut).getDeadSlot())) {
919 OS << (First ? " - " : ",") << I;
920 First = false;
921 }
922 }
923 OS << (First ? " --> " : " -> ");
924
925 // Then display regions in which the register is used.
926 auto It = PrintReg.Uses.begin();
927 OS << It->first;
928 while (++It != PrintReg.Uses.end())
929 OS << "," << It->first;
930 }
931 OS << "] ";
932 }
933 if (PrintReg.isAlive()) {
934 PrintReg.DefMI->print(OS, /*IsStandalone=*/true, /*SkipOpers=*/false,
935 /*SkipDebugLoc=*/false, /*AddNewLine=*/false);
936 OS << " @ ";
937 LIS.getInstructionIndex(*PrintReg.DefMI).print(OS);
938 }
939 });
940}
941
943 return Printable([&, RegIdx](raw_ostream &OS) {
944 for (const auto &[UseRegion, Users] : getReg(RegIdx).Uses) {
945 for (MachineInstr *MI : Users)
946 OS << " User " << printUser(MI, UseRegion) << '\n';
947 }
948 });
949}
950
952 std::optional<unsigned> UseRegion) const {
953 return Printable([&, MI, UseRegion](raw_ostream &OS) {
954 RegisterIdx RegIdx = getDefRegIdx(*MI);
955 if (RegIdx != NoReg) {
956 OS << printID(RegIdx);
957 } else {
958 OS << "(-/-)[";
959 if (UseRegion)
960 OS << *UseRegion;
961 else
962 OS << '?';
963 OS << ']';
964 }
965 OS << ' ';
966 MI->print(OS, /*IsStandalone=*/true, /*SkipOpers=*/false,
967 /*SkipDebugLoc=*/false, /*AddNewLine=*/false);
968 OS << " @ ";
969 LIS.getInstructionIndex(*MI).print(OS);
970 });
971}
972
974 RegisterIdx RegIdx) {
975 if (RollingBack)
976 return;
977 assert(Remater.isRematerializedRegister(RegIdx) && "only remats are created");
978 Rematerializations[Remater.getOriginOf(RegIdx)].insert(RegIdx);
979}
980
982 const Rematerializer &Remater, RegisterIdx RegIdx) {
983 if (RollingBack)
984 return;
985
986 // Find a valid re-creation position after the register's definition.
987 MachineInstr *DefMI = Remater.getReg(RegIdx).DefMI;
988 MachineBasicBlock *ParentMBB = DefMI->getParent();
989 MachineBasicBlock::iterator ValidPos = std::next(DefMI->getIterator());
990 while (ValidPos != ParentMBB->end() && isRollbackableMI(*ValidPos, Remater))
991 ValidPos = std::next(ValidPos);
992
993 if (Remater.isRematerializedRegister(RegIdx)) {
994 // Rematerializations will not be re-created. Previously deleted registers
995 // that reference this register's defining instruction as their re-creation
996 // position should instead be re-created at a valid position after the
997 // deleted MI.
998 invalidatePosition(DefMI, ValidPos);
999 return;
1000 }
1001
1002 // Original registers can be re-created. Add a re-creation position for the
1003 // definition of the rematerializable register.
1004 DeadRegs.push_back(DeadReg(RegIdx, Remater));
1005 const InsertBeforePos InsertPos = makePos(ValidPos, ParentMBB);
1006 PosToIdx[InsertPos].insert(Positions.size());
1007 Positions.push_back(InsertPos);
1008}
1009
1011 const Rematerializer &Remater, MachineInstr &MI) {
1012 if (RollingBack)
1013 return;
1014
1015 // Previously deleted registers that reference this MI as their re-creation
1016 // position should instead be re-created at a valid position after it.
1017 MachineBasicBlock *ParentMBB = MI.getParent();
1018 MachineBasicBlock::iterator ValidPos = std::next(MI.getIterator());
1019 while (ValidPos != ParentMBB->end() && isRollbackableMI(*ValidPos, Remater))
1020 ValidPos = std::next(ValidPos);
1021 invalidatePosition(&MI, ValidPos);
1022}
1023
1025 RollingBack = true;
1026
1027 // As we re-create registers, map deleted definitions to re-created ones. This
1028 // allows to replace invalid re-creation positions that reference deleted
1029 // definitions to valid new positions while restoring original MI order.
1031 unsigned PositionIndex = Positions.size();
1032
1033 // Re-create deleted registers in reverse order of deletion. Related registers
1034 // are deleted in reverse def-use order so this ensures we re-create registers
1035 // in def-use order. This also ensures that re-creation positions that became
1036 // invalid due to later MI deletions can be corrected as we go.
1037 for (const DeadReg &Reg : reverse(DeadRegs)) {
1038 if (Remater.isPermanentlyDead(Reg.Idx)) {
1039 // It is possible the register was permanently deleted as a consequence of
1040 // dead-def elimination.
1041 Rematerializations.erase(Reg.Idx);
1042 --PositionIndex;
1043 continue;
1044 }
1045
1046 assert(!Remater.getReg(Reg.Idx).isAlive() && "register should be dead");
1047
1048 // Determine re-creation position for the register's definition.
1050 InsertBeforePos Pos = Positions[--PositionIndex];
1051 if (auto *MBB = dyn_cast<MachineBasicBlock *>(Pos)) {
1052 InsertPosition = MBB->end();
1053 } else {
1054 auto *MI = cast<MachineInstr *>(Pos);
1055 InsertPosition = Replacements.lookup_or(MI, MI)->getIterator();
1056 }
1057
1058 Remater.recreateReg(Reg.Idx, InsertPosition, Reg.DefReg);
1059
1060 const Rematerializer::Reg &RecreateReg = Remater.getReg(Reg.Idx);
1061 if (!Replacements.insert({Reg.DefMI, RecreateReg.DefMI}).second)
1062 llvm_unreachable("duplicate deleted MI");
1063 }
1064
1065 // Rollback rematerializations.
1066 for (const auto &[RegIdx, RematsOf] : Rematerializations) {
1067 for (RegisterIdx RematRegIdx : RematsOf) {
1068 // It is possible that rematerializations were deleted. Their users would
1069 // have been transfered to some other rematerialization so we can safely
1070 // ignore them. Original registers that were deleted were just re-created
1071 // so we do not need to check for that.
1072 if (Remater.getReg(RematRegIdx).isAlive())
1073 Remater.transferAllUsers(RematRegIdx, RegIdx);
1074 }
1075 }
1076
1077 DeadRegs.clear();
1078 Positions.clear();
1079 PosToIdx.clear();
1080 Rematerializations.clear();
1081 RollingBack = false;
1082}
1083
1084bool Rollbacker::isRollbackableMI(const MachineInstr &MI,
1085 const Rematerializer &Remater) const {
1086 RegisterIdx RegIdx = Remater.getDefRegIdx(MI);
1087 if (RegIdx == Rematerializer::NoReg ||
1088 !Remater.isRematerializedRegister(RegIdx))
1089 return false;
1090 // It is possible that the MI defines a rematerializable register that was not
1091 // recorded if the rollbacker was attached to the rematerializer after the
1092 // rematerialization happened. In such cases the MI won't be rolled back.
1093 auto RematsOf = Rematerializations.find(Remater.getOriginOf(RegIdx));
1094 if (RematsOf == Rematerializations.end())
1095 return false;
1096 return RematsOf->getSecond().contains(RegIdx);
1097}
1098
1099void Rollbacker::invalidatePosition(MachineInstr *MI,
1101 const InsertBeforePos MIPos = InsertBeforePos(MI),
1102 NewPos = makePos(It, MI->getParent());
1103 auto MIIndices = PosToIdx.find(MIPos);
1104 if (MIIndices == PosToIdx.end())
1105 return;
1106 const SmallDenseSet<unsigned, 1> &InvalIndices = MIIndices->getSecond();
1107 assert(!InvalIndices.empty() && "no index hold position");
1108 for (unsigned I : InvalIndices)
1109 Positions[I] = NewPos;
1110 PosToIdx.try_emplace(NewPos).first->getSecond().insert_range(InvalIndices);
1111 PosToIdx.erase(MIPos);
1112}
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
IRTranslator LLVM IR MI
iv Induction Variable Users
Definition IVUsers.cpp:48
#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
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.
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)
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.
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.
const MachineOperand & getOperand(unsigned i) const
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.
MachineOperand * getOneDef(Register Reg) const
Returns the defining operand if there is exactly one operand defining the specified register,...
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
LLVM_ABI LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
std::pair< iterator, bool > try_emplace(const KeyT &Key, Ts &&...Args)
Definition MapVector.h:118
VectorType takeVector()
Clear the MapVector and return the underlying vector.
Definition MapVector.h:50
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
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
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, MachineBasicBlock::iterator InsertPos, Register DefReg)
Re-creates a previously deleted register RegIdx before InsertPos, which must be in the register's ori...
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 printRematReg(RegisterIdx RegIdx, bool SkipRegions=false) const
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 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:151
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
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:339
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
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
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
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 defined by a single machine instruction.
MachineInstr * DefMI
Single MI defining the rematerializable register.
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.
unsigned DefRegion
Defining region of DefMI.
SmallDenseMap< unsigned, RegionUsers, 2 > Uses
Uses of the register, mapped by region.
Register getDefReg() const
Returns the rematerializable register from its defining instruction.
SmallVector< RegisterIdx, 2 > Dependencies
This register's rematerializable dependencies, one per unique rematerializable register operand.
SmallDenseSet< MachineInstr *, 4 > RegionUsers
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:342