28#define DEBUG_TYPE "rematerializer"
34void Rematerializer::Listener::anchor() {}
47 if ((SR.LaneMask & Mask).none())
49 if (!SR.liveAt(UseIdx))
67 if (
Reg.isPhysical()) {
83 FirstMI ? FirstMI : Regions[UseRegion].second;
110 NewDepRegIdx = RematIdx->second;
121 transferUserImpl(FromRegIdx, ToRegIdx, UserMI);
122 Regs[FromRegIdx].eraseUser(&UserMI, UserRegion);
123 Regs[ToRegIdx].addUser(&UserMI, UserRegion);
124 deleteRegIfUnused(FromRegIdx);
129 unsigned UseRegion) {
130 auto &FromRegUsers = Regs[FromRegIdx].Uses;
131 auto UsesIt = FromRegUsers.find(UseRegion);
132 if (UsesIt == FromRegUsers.end())
137 transferUserImpl(FromRegIdx, ToRegIdx, *UserMI);
138 Regs[ToRegIdx].addUsers(RegionUsers, UseRegion);
139 FromRegUsers.erase(UseRegion);
140 deleteRegIfUnused(FromRegIdx);
145 Reg &FromReg = Regs[FromRegIdx], &ToReg = Regs[ToRegIdx];
146 for (
const auto &[UseRegion, RegionUsers] : FromReg.
Uses) {
148 transferUserImpl(FromRegIdx, ToRegIdx, *UserMI);
149 ToReg.addUsers(RegionUsers, UseRegion);
151 FromReg.
Uses.clear();
152 deleteRegIfUnused(FromRegIdx);
155void Rematerializer::transferUserImpl(
RegisterIdx FromRegIdx,
158 assert(FromRegIdx != ToRegIdx &&
"identical registers");
160 "unrelated registers");
167 LISUpdates.insert(FromRegIdx);
168 LISUpdates.insert(ToRegIdx);
174 for (Reg::Dependency &Dep : Regs[UserRegIdx].Dependencies) {
175 if (Dep.RegIdx == FromRegIdx) {
176 Dep.RegIdx = ToRegIdx;
191 if (LIS.hasInterval(DefReg))
192 LIS.removeInterval(DefReg);
196 LIS.createAndComputeVirtRegInterval(DefReg);
199 dbgs() <<
"Re-computed interval for " <<
printID(RegIdx) <<
": ";
200 LIS.getInterval(DefReg).print(
dbgs());
207 if (!SeenUnrematRegs.
insert(UnrematReg).second)
209 LIS.removeInterval(UnrematReg);
210 bool NeedSplit =
false;
218 LIS.createAndComputeVirtRegInterval(UnrematReg, NeedSplit);
221 LIS.splitSeparateComponents(LI, SplitLIs);
224 dbgs() <<
" Re-computed interval for register "
240 LaneBitmask Mask = SubIdx ? TRI.getSubRegIndexLaneMask(SubIdx)
241 : MRI.getMaxLaneMaskForVReg(
Reg);
256 if (It == Rematerializations.end())
258 const RematsOf &Remats = It->getSecond();
263 const Reg &RematReg =
getReg(RematRegIdx);
268 if (RematRegSlot < Before &&
269 (BestRegIdx ==
NoReg || RematRegSlot > BestSlot)) {
270 BestSlot = RematRegSlot;
271 BestRegIdx = RematRegIdx;
277void Rematerializer::deleteRegIfUnused(
RegisterIdx RootIdx) {
285 DeleteOrder.
insert(RootIdx);
289 for (
const Reg::Dependency &Dep : DeleteReg.Dependencies) {
291 Reg &DepReg = Regs[Dep.RegIdx];
292 DepReg.eraseUser(DeleteReg.DefMI, DeleteReg.DefRegion);
293 if (DepReg.Uses.empty()) {
294 DeleteOrder.
insert(Dep.RegIdx);
298 }
while (!DepDAG.
empty());
301 Reg &DeleteReg = Regs[RegIdx];
305 Register DefReg = DeleteReg.getDefReg();
306 if (LIS.hasInterval(DefReg))
307 LIS.removeInterval(DefReg);
308 LISUpdates.erase(RegIdx);
314 RematsOf &OriginRemats = Rematerializations.at(OriginIdx);
315 assert(OriginRemats.contains(RegIdx) &&
"broken remat<->origin link");
316 OriginRemats.erase(RegIdx);
317 if (OriginRemats.empty())
318 Rematerializations.erase(OriginIdx);
324void Rematerializer::deleteReg(
RegisterIdx RegIdx) {
325 noteRegDeleted(RegIdx);
327 Reg &DeleteReg = Regs[RegIdx];
328 assert(DeleteReg.DefMI &&
"register was already deleted");
332 if (RegionBegin == DeleteReg.DefMI)
334 LIS.RemoveMachineInstrFromMaps(*DeleteReg.DefMI);
335 DeleteReg.DefMI->eraseFromParent();
336 DeleteReg.DefMI =
nullptr;
342 : Regions(Regions), MRI(MF.getRegInfo()), LIS(LIS),
343 TII(*MF.getSubtarget().getInstrInfo()), TRI(TII.getRegisterInfo()) {
344#ifdef EXPENSIVE_CHECKS
347 for (
const auto &[RegionBegin, RegionEnd] : Regions) {
348 assert(RegionBegin != RegionEnd &&
"empty region");
349 for (
auto MI = RegionBegin;
MI != RegionEnd; ++
MI) {
350 bool IsNewMI = SeenMIs.
insert(&*
MI).second;
351 assert(IsNewMI &&
"overlapping regions");
352 assert(!
MI->isTerminator() &&
"terminator in region");
354 if (RegionEnd != RegionBegin->getParent()->end()) {
355 bool IsNewMI = SeenMIs.
insert(&*RegionEnd).second;
356 assert(IsNewMI &&
"overlapping regions (upper bound)");
364 UnrematableOprds.clear();
366 Rematerializations.clear();
378 RegionMBB.
reserve(Regions.size());
379 for (
unsigned I = 0, E = Regions.size();
I < E; ++
I) {
387 RegionMBB.push_back(&
MBB);
392 assert(!MIRegion.
contains(RegionTerm) &&
"regions should not intersect");
393 MIRegion.
insert({RegionTerm,
I});
397 const unsigned NumVirtRegs = MRI.getNumVirtRegs();
399 for (
unsigned I = 0, E = NumVirtRegs;
I != E; ++
I) {
401 addRegIfRematerializable(
I, MIRegion, SeenRegs);
403 assert(Regs.size() == UnrematableOprds.size());
409 return !Regs.empty();
412void Rematerializer::addRegIfRematerializable(
415 assert(!SeenRegs[VirtRegIdx] &&
"register already seen");
417 SeenRegs.
set(VirtRegIdx);
423 if (!isMIRematerializable(
DefMI))
426 if (DefRegion == MIRegion.
end())
430 RematReg.DefMI = &
DefMI;
431 RematReg.DefRegion = DefRegion->second;
432 unsigned SubIdx =
DefMI.getOperand(0).getSubReg();
433 RematReg.Mask = SubIdx ?
TRI.getSubRegIndexLaneMask(SubIdx)
440 if (
auto UseRegion = MIRegion.
find(&
UseMI); UseRegion != MIRegion.
end())
441 RematReg.addUser(&
UseMI, UseRegion->second);
445 if (RematReg.Uses.empty())
452 for (
const auto &[MOIdx, MO] :
enumerate(RematReg.DefMI->operands())) {
454 if (!DepReg || !AllDepRegs.
insert(DepReg).second)
457 if (!SeenRegs[DepRegIdx])
458 addRegIfRematerializable(DepRegIdx, MIRegion, SeenRegs);
459 if (
auto DepIt = RegToIdx.find(DepReg); DepIt != RegToIdx.end())
460 RematReg.Dependencies.push_back(Reg::Dependency(MOIdx, DepIt->second));
466 RegToIdx.
insert({DefReg, Regs.size()});
467 Regs.push_back(RematReg);
468 UnrematableOprds.push_back(UnrematDeps);
471bool Rematerializer::isMIRematerializable(
const MachineInstr &
MI)
const {
472 if (!TII.isReMaterializable(
MI))
475 assert(
MI.getOperand(0).getReg().isVirtual() &&
"should be virtual");
476 assert(MRI.hasOneDef(
MI.getOperand(0).getReg()) &&
"should have single def");
478 for (
const MachineOperand &MO :
MI.all_uses()) {
482 if (MRI.isConstantPhysReg(MO.
getReg()) || TII.isIgnorableUse(MO))
492 if (!
MI.getNumOperands() || !
MI.getOperand(0).isReg() ||
493 MI.getOperand(0).readsReg())
496 auto UserRegIt = RegToIdx.find(
Reg);
497 if (UserRegIt == RegToIdx.end())
499 return UserRegIt->second;
508 Reg &NewReg = Regs.emplace_back();
509 Reg &FromReg = Regs[RegIdx];
518 Origins.push_back(OriginIdx);
519 Rematerializations[OriginIdx].insert(NewRegIdx);
524 TII.reMaterialize(*RegionMBB[UseRegion], InsertPos, NewDefReg, 0,
526 NewReg.
DefMI = &*std::prev(InsertPos);
527 RegToIdx.insert({NewDefReg, NewRegIdx});
528 postRematerialization(RegIdx, NewRegIdx, InsertPos);
530 noteRegCreated(NewRegIdx);
540 assert(RegToIdx.contains(DefReg) &&
"unknown defined register");
541 assert(RegToIdx.at(DefReg) == RegIdx &&
"incorrect defined register");
544 Reg &OriginReg = Regs[RegIdx];
550 if (!RecreateOriginalReg)
551 Rematerializations[
getOriginOf(RegIdx)].insert(RegIdx);
557 if (RecreateOriginalReg) {
558 assert(Rematerializations.contains(RegIdx) &&
"expected remats");
559 ModelRegIdx = *Rematerializations.at(RegIdx).begin();
566 TII.reMaterialize(*RegionMBB[DefRegion], InsertPos, DefReg, 0, ModelDefMI);
567 OriginReg.
DefMI = &*std::prev(InsertPos);
568 postRematerialization(ModelRegIdx, RegIdx, InsertPos);
573void Rematerializer::postRematerialization(
578 Reg &ModelReg = Regs[ModelRegIdx], &RematReg = Regs[RematRegIdx];
582 RegionBegin = RematReg.DefMI;
586 auto ZipedDeps =
zip_equal(ModelReg.Dependencies, RematReg.Dependencies);
587 for (
const auto &[OldDep, NewDep] : ZipedDeps) {
588 assert(OldDep.MOIdx == NewDep.MOIdx &&
"operand mismatch");
590 <<
printID(OldDep.RegIdx) <<
" -> "
591 <<
printID(NewDep.RegIdx) <<
'\n');
593 Reg &NewDepReg = Regs[NewDep.RegIdx];
594 if (OldDep.RegIdx != NewDep.RegIdx) {
595 Register OldDefReg = ModelReg.DefMI->getOperand(OldDep.MOIdx).getReg();
596 RematReg.DefMI->substituteRegister(OldDefReg, NewDepReg.getDefReg(), 0,
598 LISUpdates.insert(OldDep.RegIdx);
600 NewDepReg.addUser(RematReg.DefMI, RematReg.DefRegion);
601 LISUpdates.insert(NewDep.RegIdx);
605std::pair<MachineInstr *, MachineInstr *>
608 auto It =
Uses.find(UseRegion);
609 if (It ==
Uses.end())
610 return {
nullptr,
nullptr};
616 SlotIndex FirstIndex = LIS.getInstructionIndex(*FirstMI),
617 LastIndex = FirstIndex;
619 while (++
User != UserEnd) {
621 if (UserIndex < FirstIndex) {
622 FirstIndex = UserIndex;
624 }
else if (UserIndex > LastIndex) {
625 LastIndex = UserIndex;
630 return {FirstMI, LastMI};
637void Rematerializer::Reg::addUsers(
const RegionUsers &NewUsers,
644 assert(RUsers.contains(
MI) &&
"user not in region");
645 if (RUsers.size() == 1)
654 std::function<void(
RegisterIdx,
unsigned)> WalkTree =
659 WalkTree(Dep.RegIdx,
Depth + 1);
661 WalkTree(RootIdx, 0);
666 sort(Regs, [](
const auto &LHS,
const auto &RHS) {
667 return LHS.second > RHS.second;
670 OS <<
printID(RootIdx) <<
" has " << Regs.size() - 1 <<
" dependencies\n";
671 for (
const auto &[RegIdx,
Depth] : Regs) {
682 OS <<
'(' << RegIdx <<
'/';
683 if (!PrintReg.
DefMI) {
694 bool SkipRegions)
const {
699 if (!PrintReg.
Uses.empty()) {
700 assert(PrintReg.
DefMI &&
"dead register cannot have uses");
705 for (
const auto [
I, Bounds] :
enumerate(Regions)) {
706 if (Bounds.first == Bounds.second)
708 if (!PrintReg.
Uses.contains(
I) &&
709 LI.
liveAt(LIS.getInstructionIndex(*Bounds.first)) &&
710 LI.
liveAt(LIS.getInstructionIndex(*std::prev(Bounds.second))
712 OS << (
First ?
" - " :
",") <<
I;
716 OS << (
First ?
" --> " :
" -> ");
719 auto It = PrintReg.
Uses.begin();
721 while (++It != PrintReg.
Uses.end())
722 OS <<
"," << It->first;
730 LIS.getInstructionIndex(*PrintReg.
DefMI).print(OS);
738 OS <<
" User " <<
printUser(
MI, UseRegion) <<
'\n';
744 std::optional<unsigned> UseRegion)
const {
747 if (RegIdx !=
NoReg) {
758 MI->print(OS,
true,
false,
761 LIS.getInstructionIndex(*MI).print(OS);
765Rollbacker::RollbackInfo::RollbackInfo(
const Rematerializer &Remater,
768 DefReg = Reg.getDefReg();
769 DefRegion = Reg.DefRegion;
770 Dependencies = Reg.Dependencies;
772 InsertPos = std::next(Reg.DefMI->getIterator());
773 if (InsertPos != Reg.DefMI->getParent()->end())
783 Rematerializations[Remater.
getOriginOf(RegIdx)].insert(RegIdx);
790 DeadRegs.try_emplace(RegIdx, Remater, RegIdx);
797 for (
auto &[RegIdx, Info] : DeadRegs) {
807 const auto *NextRegRollback = DeadRegs.find(NextRegIdx);
808 if (NextRegRollback == DeadRegs.end())
810 InsertPos = NextRegRollback->second.InsertPos;
811 NextRegIdx = NextRegRollback->second.NextRegIdx;
813 Remater.
recreateReg(RegIdx, Info.DefRegion, InsertPos, Info.DefReg,
814 std::move(Info.Dependencies));
818 for (
const auto &[RegIdx,
RematsOf] : Rematerializations) {
831 Rematerializations.clear();
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
iv Induction Variable Users
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
Promote Memory to Register
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 implements a set that has insertion order iteration characteristics.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
BitVector & set()
Set all bits in the bitvector.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > emplace_or_assign(const KeyT &Key, Ts &&...Args)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
ValueT lookup_or(const_arg_type_t< KeyT > Val, U &&Default) const
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
Implements a dense probed hash-table based set.
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
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.
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...
Simple wrapper around std::function<void(raw_ostream&)>.
RegionT * getParent() const
Get the parent of the Region.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
unsigned virtRegIndex() const
Convert a virtual register number to a 0-based index.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
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 rematerializeReg(RegisterIdx RegIdx, unsigned UseRegion, MachineBasicBlock::iterator InsertPos, SmallVectorImpl< Reg::Dependency > &&Dependencies)
Rematerializes register RegIdx before InsertPos in UseRegion, adding the new rematerializable registe...
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 void updateLiveIntervals()
Recomputes all live intervals that have changed as a result of previous rematerializations.
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 ...
unsigned RegisterIdx
Index type for rematerializable registers.
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.
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 ...
ArrayRef< unsigned > getUnrematableOprds(RegisterIdx RegIdx) const
Returns operand indices corresponding to unrematerializable operands for any register RegIdx.
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...
bool isRematerializedRegister(RegisterIdx RegIdx) const
Whether register RegIdx is a rematerialization of some original register.
LLVM_ABI void recreateReg(RegisterIdx RegIdx, unsigned DefRegion, MachineBasicBlock::iterator InsertPos, Register DefReg, SmallVectorImpl< Reg::Dependency > &&Dependencies)
Re-creates a previously deleted register RegIdx before InsertPos in DefRegion.
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 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 rematerializerNoteRegCreated(const Rematerializer &Remater, RegisterIdx RegIdx) override
Called just after register NewRegIdx is created (following a rematerialization).
void rematerializerNoteRegDeleted(const Rematerializer &Remater, RegisterIdx RegIdx) override
Called juste before register RegIdx is deleted from the MIR.
bool insert(const value_type &X)
Insert a new element into the SetVector.
SlotIndex - An opaque wrapper around machine indexes.
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.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
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.
VNInfo - Value Number Information.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
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.
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 read register operand of DefMI that is rematerializable (according to the rematerializer).
A rematerializable register defined by a single machine instruction.
MachineInstr * DefMI
Single MI defining the rematerializable register.
SmallVector< Dependency, 2 > Dependencies
This register's rematerializable dependencies, one per unique rematerializable register operand.
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.
SmallDenseSet< MachineInstr *, 4 > RegionUsers