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 assert(OriginRemats.contains(RegIdx) &&
"broken remat<->origin link");
315 OriginRemats.erase(RegIdx);
316 if (OriginRemats.empty())
317 Rematerializations.erase(RegIdx);
323void Rematerializer::deleteReg(
RegisterIdx RegIdx) {
324 noteRegDeleted(RegIdx);
326 Reg &DeleteReg = Regs[RegIdx];
327 assert(DeleteReg.DefMI &&
"register was already deleted");
331 if (RegionBegin == DeleteReg.DefMI)
333 LIS.RemoveMachineInstrFromMaps(*DeleteReg.DefMI);
334 DeleteReg.DefMI->eraseFromParent();
335 DeleteReg.DefMI =
nullptr;
341 : Regions(Regions), MRI(MF.getRegInfo()), LIS(LIS),
342 TII(*MF.getSubtarget().getInstrInfo()), TRI(TII.getRegisterInfo()) {
343#ifdef EXPENSIVE_CHECKS
346 for (
const auto &[RegionBegin, RegionEnd] : Regions) {
347 assert(RegionBegin != RegionEnd &&
"empty region");
348 for (
auto MI = RegionBegin;
MI != RegionEnd; ++
MI) {
349 bool IsNewMI = SeenMIs.
insert(&*
MI).second;
350 assert(IsNewMI &&
"overlapping regions");
351 assert(!
MI->isTerminator() &&
"terminator in region");
353 if (RegionEnd != RegionBegin->getParent()->end()) {
354 bool IsNewMI = SeenMIs.
insert(&*RegionEnd).second;
355 assert(IsNewMI &&
"overlapping regions (upper bound)");
363 UnrematableOprds.clear();
365 Rematerializations.clear();
377 RegionMBB.
reserve(Regions.size());
378 for (
unsigned I = 0, E = Regions.size();
I < E; ++
I) {
386 RegionMBB.push_back(&
MBB);
391 assert(!MIRegion.
contains(RegionTerm) &&
"regions should not intersect");
392 MIRegion.
insert({RegionTerm,
I});
396 const unsigned NumVirtRegs = MRI.getNumVirtRegs();
398 for (
unsigned I = 0, E = NumVirtRegs;
I != E; ++
I) {
400 addRegIfRematerializable(
I, MIRegion, SeenRegs);
402 assert(Regs.size() == UnrematableOprds.size());
408 return !Regs.empty();
411void Rematerializer::addRegIfRematerializable(
414 assert(!SeenRegs[VirtRegIdx] &&
"register already seen");
416 SeenRegs.
set(VirtRegIdx);
422 if (!isMIRematerializable(
DefMI))
425 if (DefRegion == MIRegion.
end())
429 RematReg.DefMI = &
DefMI;
430 RematReg.DefRegion = DefRegion->second;
431 unsigned SubIdx =
DefMI.getOperand(0).getSubReg();
432 RematReg.Mask = SubIdx ?
TRI.getSubRegIndexLaneMask(SubIdx)
439 if (
auto UseRegion = MIRegion.
find(&
UseMI); UseRegion != MIRegion.
end())
440 RematReg.addUser(&
UseMI, UseRegion->second);
444 if (RematReg.Uses.empty())
451 for (
const auto &[MOIdx, MO] :
enumerate(RematReg.DefMI->operands())) {
453 if (!DepReg || !AllDepRegs.
insert(DepReg).second)
456 if (!SeenRegs[DepRegIdx])
457 addRegIfRematerializable(DepRegIdx, MIRegion, SeenRegs);
458 if (
auto DepIt = RegToIdx.find(DepReg); DepIt != RegToIdx.end())
459 RematReg.Dependencies.push_back(Reg::Dependency(MOIdx, DepIt->second));
465 RegToIdx.
insert({DefReg, Regs.size()});
466 Regs.push_back(RematReg);
467 UnrematableOprds.push_back(UnrematDeps);
470bool Rematerializer::isMIRematerializable(
const MachineInstr &
MI)
const {
471 if (!TII.isReMaterializable(
MI))
474 assert(
MI.getOperand(0).getReg().isVirtual() &&
"should be virtual");
475 assert(MRI.hasOneDef(
MI.getOperand(0).getReg()) &&
"should have single def");
477 for (
const MachineOperand &MO :
MI.all_uses()) {
481 if (MRI.isConstantPhysReg(MO.
getReg()) || TII.isIgnorableUse(MO))
491 if (!
MI.getNumOperands() || !
MI.getOperand(0).isReg() ||
492 MI.getOperand(0).readsReg())
495 auto UserRegIt = RegToIdx.find(
Reg);
496 if (UserRegIt == RegToIdx.end())
498 return UserRegIt->second;
507 Reg &NewReg = Regs.emplace_back();
508 Reg &FromReg = Regs[RegIdx];
517 Origins.push_back(OriginIdx);
518 Rematerializations[OriginIdx].insert(NewRegIdx);
523 TII.reMaterialize(*RegionMBB[UseRegion], InsertPos, NewDefReg, 0,
525 NewReg.
DefMI = &*std::prev(InsertPos);
526 RegToIdx.insert({NewDefReg, NewRegIdx});
527 postRematerialization(RegIdx, NewRegIdx, InsertPos);
529 noteRegCreated(NewRegIdx);
539 assert(RegToIdx.contains(DefReg) &&
"unknown defined register");
540 assert(RegToIdx.at(DefReg) == RegIdx &&
"incorrect defined register");
543 Reg &OriginReg = Regs[RegIdx];
549 if (!RecreateOriginalReg)
550 Rematerializations[
getOriginOf(RegIdx)].insert(RegIdx);
556 if (RecreateOriginalReg) {
557 assert(Rematerializations.contains(RegIdx) &&
"expected remats");
558 ModelRegIdx = *Rematerializations.at(RegIdx).begin();
565 TII.reMaterialize(*RegionMBB[DefRegion], InsertPos, DefReg, 0, ModelDefMI);
566 OriginReg.
DefMI = &*std::prev(InsertPos);
567 postRematerialization(ModelRegIdx, RegIdx, InsertPos);
572void Rematerializer::postRematerialization(
577 Reg &ModelReg = Regs[ModelRegIdx], &RematReg = Regs[RematRegIdx];
581 RegionBegin = RematReg.DefMI;
585 auto ZipedDeps =
zip_equal(ModelReg.Dependencies, RematReg.Dependencies);
586 for (
const auto &[OldDep, NewDep] : ZipedDeps) {
587 assert(OldDep.MOIdx == NewDep.MOIdx &&
"operand mismatch");
589 <<
printID(OldDep.RegIdx) <<
" -> "
590 <<
printID(NewDep.RegIdx) <<
'\n');
592 Reg &NewDepReg = Regs[NewDep.RegIdx];
593 if (OldDep.RegIdx != NewDep.RegIdx) {
594 Register OldDefReg = ModelReg.DefMI->getOperand(OldDep.MOIdx).getReg();
595 RematReg.DefMI->substituteRegister(OldDefReg, NewDepReg.getDefReg(), 0,
597 LISUpdates.insert(OldDep.RegIdx);
599 NewDepReg.addUser(RematReg.DefMI, RematReg.DefRegion);
600 LISUpdates.insert(NewDep.RegIdx);
604std::pair<MachineInstr *, MachineInstr *>
607 auto It =
Uses.find(UseRegion);
608 if (It ==
Uses.end())
609 return {
nullptr,
nullptr};
615 SlotIndex FirstIndex = LIS.getInstructionIndex(*FirstMI),
616 LastIndex = FirstIndex;
618 while (++
User != UserEnd) {
620 if (UserIndex < FirstIndex) {
621 FirstIndex = UserIndex;
623 }
else if (UserIndex > LastIndex) {
624 LastIndex = UserIndex;
629 return {FirstMI, LastMI};
636void Rematerializer::Reg::addUsers(
const RegionUsers &NewUsers,
643 assert(RUsers.contains(
MI) &&
"user not in region");
644 if (RUsers.size() == 1)
653 std::function<void(
RegisterIdx,
unsigned)> WalkTree =
658 WalkTree(Dep.RegIdx,
Depth + 1);
660 WalkTree(RootIdx, 0);
665 sort(Regs, [](
const auto &LHS,
const auto &RHS) {
666 return LHS.second > RHS.second;
669 OS <<
printID(RootIdx) <<
" has " << Regs.size() - 1 <<
" dependencies\n";
670 for (
const auto &[RegIdx,
Depth] : Regs) {
681 OS <<
'(' << RegIdx <<
'/';
682 if (!PrintReg.
DefMI) {
693 bool SkipRegions)
const {
698 if (!PrintReg.
Uses.empty()) {
699 assert(PrintReg.
DefMI &&
"dead register cannot have uses");
704 for (
const auto [
I, Bounds] :
enumerate(Regions)) {
705 if (Bounds.first == Bounds.second)
707 if (!PrintReg.
Uses.contains(
I) &&
708 LI.
liveAt(LIS.getInstructionIndex(*Bounds.first)) &&
709 LI.
liveAt(LIS.getInstructionIndex(*std::prev(Bounds.second))
711 OS << (
First ?
" - " :
",") <<
I;
715 OS << (
First ?
" --> " :
" -> ");
718 auto It = PrintReg.
Uses.begin();
720 while (++It != PrintReg.
Uses.end())
721 OS <<
"," << It->first;
729 LIS.getInstructionIndex(*PrintReg.
DefMI).print(OS);
737 OS <<
" User " <<
printUser(
MI, UseRegion) <<
'\n';
743 std::optional<unsigned> UseRegion)
const {
746 if (RegIdx !=
NoReg) {
757 MI->print(OS,
true,
false,
760 LIS.getInstructionIndex(*MI).print(OS);
764Rollbacker::RollbackInfo::RollbackInfo(
const Rematerializer &Remater,
767 DefReg = Reg.getDefReg();
768 DefRegion = Reg.DefRegion;
769 Dependencies = Reg.Dependencies;
771 InsertPos = std::next(Reg.DefMI->getIterator());
772 if (InsertPos != Reg.DefMI->getParent()->end())
782 Rematerializations[Remater.
getOriginOf(RegIdx)].insert(RegIdx);
789 DeadRegs.try_emplace(RegIdx, Remater, RegIdx);
796 for (
auto &[RegIdx, Info] : DeadRegs) {
806 const auto *NextRegRollback = DeadRegs.find(NextRegIdx);
807 if (NextRegRollback == DeadRegs.end())
809 InsertPos = NextRegRollback->second.InsertPos;
810 NextRegIdx = NextRegRollback->second.NextRegIdx;
812 Remater.
recreateReg(RegIdx, Info.DefRegion, InsertPos, Info.DefReg,
813 std::move(Info.Dependencies));
817 for (
const auto &[RegIdx,
RematsOf] : Rematerializations) {
830 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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
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.
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.
Printable printID(RegisterIdx RegIdx) const
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...
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
void updateLiveIntervals()
Recomputes all live intervals that have changed as a result of previous rematerializations.
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.
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.
bool isMOIdenticalAtUses(MachineOperand &MO, ArrayRef< SlotIndex > Uses) const
Determines whether (sub-)register operand MO has the same value at all Uses as at MO.
void transferRegionUsers(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx, unsigned UseRegion)
Transfers all users of register FromRegIdx in region UseRegion to ToRegIdx, the latter of which must ...
Rematerializer(MachineFunction &MF, SmallVectorImpl< RegionBoundaries > &Regions, LiveIntervals &LIS)
Simply initializes some internal state, does not identify rematerialization candidates.
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.
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.
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.
Printable printRematReg(RegisterIdx RegIdx, bool SkipRegions=false) const
Printable printRegUsers(RegisterIdx RegIdx) const
Printable printUser(const MachineInstr *MI, std::optional< unsigned > UseRegion=std::nullopt) const
RegisterIdx findRematInRegion(RegisterIdx RegIdx, unsigned Region, SlotIndex Before) const
Finds the closest rematerialization of register RegIdx in region Region that exists before slot Befor...
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.
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