36#define DEBUG_TYPE "regalloc"
38STATISTIC(NumAssigned ,
"Number of registers assigned");
39STATISTIC(NumUnassigned ,
"Number of registers unassigned");
43 "Live Register Matrix",
false,
false)
59 LRM.init(MF, LIS, VRM);
69 unsigned NumRegUnits = TRI->getNumRegUnits();
70 if (NumRegUnits != Matrix.size())
72 Matrix.
init(*LIUAlloc, NumRegUnits);
80void LiveRegMatrix::releaseMemory() {
81 for (
unsigned i = 0, e =
Matrix.size(); i != e; ++i) {
82 Matrix[
static_cast<MCRegUnit
>(i)].clear();
89template <
typename Callable>
95 MCRegUnit Unit = (*Units).first;
98 if ((S.LaneMask & Mask).any()) {
106 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
107 if (Func(Unit, VRegInterval))
117 assert(!VRM->hasPhys(VirtReg.
reg()) &&
"Duplicate VirtReg assignment");
118 VRM->assignVirt2Phys(VirtReg.
reg(), PhysReg);
121 TRI, VirtReg, PhysReg, [&](MCRegUnit Unit,
const LiveRange &
Range) {
123 Matrix[Unit].unify(VirtReg,
Range);
132 bool ClearAllReferencingSegments) {
135 <<
" from " <<
printReg(PhysReg, TRI) <<
':');
136 VRM->clearVirt(VirtReg.
reg());
138 if (!ClearAllReferencingSegments) {
142 Matrix[Unit].extract(VirtReg,
Range);
146 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
147 Matrix[Unit].clearAllSegmentsReferencing(VirtReg);
156 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
157 if (!Matrix[Unit].empty())
163bool LiveRegMatrix::checkRegMaskInterference(
const LiveInterval &VirtReg,
168 if (RegMaskVirtReg != VirtReg.
reg() || RegMaskTag != UserTag) {
169 RegMaskVirtReg = VirtReg.
reg();
170 RegMaskTag = UserTag;
171 RegMaskUsable.clear();
172 LIS->checkRegMaskInterference(VirtReg, RegMaskUsable);
178 return !RegMaskUsable.empty() &&
179 (!PhysReg || !RegMaskUsable.test(PhysReg.
id()));
182bool LiveRegMatrix::checkRegUnitInterference(
const LiveInterval &VirtReg,
189 TRI, VirtReg, PhysReg, [&](MCRegUnit Unit,
const LiveRange &
Range) {
190 const LiveRange &UnitRange = LIS->getRegUnit(Unit);
191 return Range.overlaps(UnitRange, CP, *LIS->getSlotIndexes());
203 for (; SlotI != Slots.
end() && *SlotI < End; ++SlotI) {
212 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
213 if (LIS->getRegUnit(Unit).overlaps(Start, End))
222 Q.
init(UserTag, LR, Matrix[RegUnit]);
233 if (checkRegMaskInterference(VirtReg, PhysReg))
237 if (checkRegUnitInterference(VirtReg, PhysReg))
241 bool Interference =
foreachUnit(TRI, VirtReg, PhysReg,
242 [&](MCRegUnit Unit,
const LiveRange &LR) {
254 if (checkRegMaskInterference(Start, End, PhysReg))
258 if (checkRegUnitInterference(Start, End, PhysReg))
268 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
282 Q.
reset(UserTag, LR, Matrix[Unit]);
302 auto [Unit, Lanes] = *MCRU;
316 Q.
reset(UserTag, LR, Matrix[Unit]);
318 InterferingLanes |= Lanes;
321 return InterferingLanes;
326 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
327 if ((VRegInterval = Matrix[Unit].
getOneVReg()))
328 return VRegInterval->
reg();
338 for (
unsigned RegIdx = 0, NumRegs = VRM->getRegInfo().getNumVirtRegs();
339 RegIdx < NumRegs; ++RegIdx) {
342 if (VRM->hasPhys(VReg) && LIS->hasInterval(VReg))
343 ValidIntervals.
insert(&LIS->getInterval(VReg));
347 unsigned NumDanglingPointers = 0;
348 for (
unsigned I = 0,
Size = Matrix.size();
I <
Size; ++
I) {
349 MCRegUnit Unit =
static_cast<MCRegUnit
>(
I);
352 ++NumDanglingPointers;
353 dbgs() <<
"ERROR: LiveInterval pointer is not found in LiveIntervals:\n"
354 <<
" Register Unit: " <<
printRegUnit(Unit, TRI) <<
'\n'
355 <<
" LiveInterval pointer: " << LI <<
'\n';
362 unsigned NumMissing = 0;
363 for (
unsigned RegIdx = 0, NumRegs = VRM->getRegInfo().getNumVirtRegs();
364 RegIdx < NumRegs; ++RegIdx) {
366 if (!VRM->hasPhys(VReg) || !LIS->hasInterval(VReg))
376 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
377 auto It = Matrix[Unit].find(FirstStart);
378 if (It.valid() && It.start() == FirstStart && It.value() == &LI) {
385 dbgs() <<
"ERROR: VirtReg " <<
printReg(VReg, TRI) <<
" assigned to "
387 <<
" in VirtRegMap but not found in LiveRegMatrix\n";
388 dbgs() <<
" LiveInterval: " << LI <<
"\n";
389 dbgs() <<
" FirstStart: " << FirstStart <<
"\n";
390 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
392 auto It = Matrix[Unit].find(FirstStart);
394 dbgs() <<
"[" << It.start() <<
"," << It.stop() <<
") -> "
395 <<
printReg(It.value()->reg(), TRI);
397 dbgs() <<
"(none found)";
403 return NumDanglingPointers == 0 && NumMissing == 0;
414 LRM.
init(MF, LIS, VRM);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the DenseSet and SmallDenseSet classes.
A common definition of LaneBitmask for use in TableGen and CodeGen.
static bool foreachUnit(const TargetRegisterInfo *TRI, const LiveInterval &VRegInterval, MCRegister PhysReg, Callable Func)
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
A helper class for register coalescers.
Implements a dense probed hash-table based set.
Query interferences between a single live virtual register and a live interval union.
void init(unsigned NewUserTag, const LiveRange &NewLR, const LiveIntervalUnion &NewLiveUnion)
void reset(unsigned NewUserTag, const LiveRange &NewLR, const LiveIntervalUnion &NewLiveUnion)
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()
ArrayRef< const uint32_t * > getRegMaskBits() const
Returns an array of register mask pointers corresponding to getRegMaskSlots().
ArrayRef< SlotIndex > getRegMaskSlots() const
Returns a sorted array of slot indices of all instructions with register mask operands.
This class represents the liveness of a register, stack slot, etc.
LLVM_ABI iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
SlotIndex beginIndex() const
beginIndex - Return the lowest numbered slot covered.
LLVM_ABI LiveRegMatrix run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
LiveRegMatrixWrapperLegacy()
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
LLVM_ABI bool isPhysRegUsed(MCRegister PhysReg) const
Returns true if the given PhysReg has any live intervals assigned.
void invalidateVirtRegs()
Invalidate cached interference queries after modifying virtual register live ranges.
LLVM_ABI Register getOneVReg(unsigned PhysReg) const
LLVM_ABI LiveIntervalUnion::Query & query(const LiveRange &LR, MCRegUnit RegUnit)
Query a line of the assigned virtual register matrix directly.
LLVM_ABI void unassign(const LiveInterval &VirtReg, bool ClearAllReferencingSegments=false)
Unassign VirtReg from its PhysReg.
bool isValid() const
This checks that each LiveInterval referenced in LiveIntervalUnion actually exists in LiveIntervals a...
@ IK_VirtReg
Virtual register interference.
@ IK_RegUnit
Register unit interference.
@ IK_Free
No interference, go ahead and assign.
@ IK_RegMask
RegMask interference.
LLVM_ABI void init(MachineFunction &MF, LiveIntervals &LIS, VirtRegMap &VRM)
LLVM_ABI void assign(const LiveInterval &VirtReg, MCRegister PhysReg)
Assign VirtReg to PhysReg.
LLVM_ABI InterferenceKind checkInterference(const LiveInterval &VirtReg, MCRegister PhysReg)
Check for interference before assigning VirtReg to PhysReg.
LLVM_ABI LaneBitmask checkInterferenceLanes(SlotIndex Start, SlotIndex End, MCRegister PhysReg)
Check for interference in the segment [Start, End) that may prevent assignment to PhysReg,...
MCRegUnitMaskIterator enumerates a list of register units and their associated lane masks for Reg.
bool isValid() const
Returns true if this iterator is not yet at the end.
Wrapper class representing physical registers. Should be passed by value.
static constexpr unsigned NoRegister
constexpr unsigned id() const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
SlotIndex - An opaque wrapper around machine indexes.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
VNInfo - Value Number Information.
LLVM_ABI void init(MachineFunction &MF)
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Printable printRegUnit(MCRegUnit Unit, const TargetRegisterInfo *TRI)
Create Printable object to print register units on a raw_ostream.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
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.
A special type used by analysis passes to provide an address that identifies that particular analysis...
This represents a simple continuous liveness interval for a value.