14#ifndef LLVM_CODEGEN_REMATERIALIZER_H
15#define LLVM_CODEGEN_REMATERIALIZER_H
132 assert(
DefMI &&
"defining instruction was deleted");
133 assert(
DefMI->getOperand(0).isDef() &&
"not a register def");
134 return DefMI->getOperand(0).getReg();
149 LLVM_ABI std::pair<MachineInstr *, MachineInstr *>
191 virtual void anchor();
195 static constexpr unsigned NoReg = ~0;
200 std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>;
216 assert(Listen &&
"null listener");
217 if (!Listeners.insert(Listen).second)
223 if (!Listeners.erase(Listen))
231 assert(RegIdx < Regs.size() &&
"out of bounds");
242 return !
getReg(OrigIdx).
isAlive() && !Rematerializations.contains(OrigIdx);
246 assert(RegionIdx < Regions.size() &&
"out of bounds");
247 return Regions[RegionIdx];
258 assert(RegIdx < Regs.size() &&
"out of bounds");
259 return RegIdx >= UnrematableDeps.size();
264 return Origins[RematRegIdx - UnrematableDeps.size()];
349 DependencyReuseInfo &DRI);
362 DependencyReuseInfo &DRI);
428 bool SkipRegions =
false)
const;
432 std::optional<unsigned> UseRegion = std::nullopt)
const;
438 void LRE_WillEraseInstruction(MachineInstr *
MI)
override;
441 SmallVectorImpl<RegionBoundaries> &Regions;
442 MachineRegisterInfo &MRI;
444 const TargetInstrInfo &TII;
445 const TargetRegisterInfo &TRI;
446 SmallPtrSet<Listener *, 1> Listeners;
450 Listen->rematerializerNoteRegCreated(*
this, RegIdx);
453 void noteRegWillBeDeleted(
RegisterIdx RegIdx)
const {
455 Listen->rematerializerNoteRegWillBeDeleted(*
this, RegIdx);
458 void noteMIWillBeDeleted(MachineInstr &
MI)
const {
460 Listen->rematerializerNoteMIWillBeDeleted(*
this,
MI);
481 DenseMap<RegisterIdx, RematsOf> Rematerializations;
486 DenseMap<Register, RegisterIdx> RegToIdx;
499 void extendInterval(LiveInterval &LI, LaneBitmask Mask,
500 SlotIndex UseIdx)
const;
524 addRegIfRematerializable(
unsigned VirtRegIdx,
525 const DenseMap<MachineInstr *, unsigned> &MIRegion,
526 BitVector &SeenRegs);
532 bool isMIRematerializable(
const MachineInstr &
MI)
const;
537 MachineInstr &UserMI);
579 : Idx(Idx), DefReg(Remater.
getReg(Idx).getDefReg()),
585 using InsertBeforePos = PointerUnion<MachineInstr *, MachineBasicBlock *>;
588 SmallVector<DeadReg> DeadRegs;
593 SmallVector<InsertBeforePos> Positions;
596 DenseMap<InsertBeforePos, SmallDenseSet<unsigned, 1>> PosToIdx;
599 DenseMap<RegisterIdx, Rematerializer::RematsOf> Rematerializations;
602 bool RollingBack =
false;
604 InsertBeforePos makePos(MachineBasicBlock::iterator It,
605 MachineBasicBlock *
MBB)
const {
606 if (It ==
MBB->end())
607 return InsertBeforePos(
MBB);
608 return InsertBeforePos(&*It);
614 bool isRollbackableMI(
const MachineInstr &
MI,
615 const Rematerializer &Remater)
const;
621 void invalidatePosition(MachineInstr *
MI, MachineBasicBlock::iterator It);
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
This file defines the PointerUnion class, which is a discriminated union of pointer types.
Rematerializer::RegisterIdx RegisterIdx
Remove Loads Into Fake Uses
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Callback methods for LiveRangeEdit owners.
MachineInstrBundleIterator< MachineInstr > iterator
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
Simple wrapper around std::function<void(raw_ostream&)>.
Wrapper class representing virtual and physical registers.
virtual void rematerializerNoteMIWillBeDeleted(const Rematerializer &Remater, MachineInstr &MI)
Called just before unrematerializable instruction MI is deleted from the MIR because it has become a ...
virtual void rematerializerNoteRegCreated(const Rematerializer &Remater, RegisterIdx NewRegIdx)
Called just after register NewRegIdx is created (following a rematerialization).
virtual ~Listener()=default
Rematerializer::RegisterIdx RegisterIdx
virtual void rematerializerNoteRegWillBeDeleted(const Rematerializer &Remater, RegisterIdx RegIdx)
Called just before register RegIdx is deleted from the MIR.
MIR-level target-independent rematerializer.
LLVM_ABI Printable printDependencyDAG(RegisterIdx RootIdx) const
void clearListeners()
Removes all listeners from the rematerializer.
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
ArrayRef< Reg > getRegs() 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 ...
const RegionBoundaries & getRegion(RegisterIdx RegionIdx) const
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 ...
unsigned getNumRegions() const
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...
void removeListener(Listener *Listen)
Removes a listener from the rematerializer.
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...
void addListener(Listener *Listen)
Adds a new listener to the rematerializer.
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).
SlotIndex - An opaque wrapper around machine indexes.
Implements a dense probed hash-table based set with some number of buckets stored inline.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
#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.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
ArrayRef(const T &OneElt) -> ArrayRef< T >
When rematerializating a register (called the "root" register in this context) to a given position,...
DependencyReuseInfo & clear()
DependencyReuseInfo & reuse(RegisterIdx DepIdx)
SmallDenseMap< RegisterIdx, RegisterIdx, 4 > DependencyMap
Keys and values are rematerializable register indices.
DependencyReuseInfo & useRemat(RegisterIdx DepIdx, RegisterIdx DepRematIdx)
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.
bool hasUsersInDefRegion() const
bool hasUsersOutsideDefRegion() const
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