LLVM 24.0.0git
LiveRegMatrix.cpp
Go to the documentation of this file.
1//===- LiveRegMatrix.cpp - Track register interference --------------------===//
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// This file defines the LiveRegMatrix analysis pass.
10//
11//===----------------------------------------------------------------------===//
12
14#include "RegisterCoalescer.h"
15#include "llvm/ADT/DenseSet.h"
16#include "llvm/ADT/Statistic.h"
27#include "llvm/MC/LaneBitmask.h"
29#include "llvm/Pass.h"
30#include "llvm/Support/Debug.h"
32#include <cassert>
33
34using namespace llvm;
35
36#define DEBUG_TYPE "regalloc"
37
38STATISTIC(NumAssigned , "Number of registers assigned");
39STATISTIC(NumUnassigned , "Number of registers unassigned");
40
43 "Live Register Matrix", false, false)
47 "Live Register Matrix", false, true)
48
50 AU.setPreservesAll();
51 AU.addRequiredTransitive<LiveIntervalsWrapperPass>();
52 AU.addRequiredTransitive<VirtRegMapWrapperLegacy>();
54}
55
57 auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
58 auto &VRM = getAnalysis<VirtRegMapWrapperLegacy>().getVRM();
59 LRM.init(MF, LIS, VRM);
60 return false;
61}
62
64 VirtRegMap &pVRM) {
65 TRI = MF.getSubtarget().getRegisterInfo();
66 LIS = &pLIS;
67 VRM = &pVRM;
68
69 unsigned NumRegUnits = TRI->getNumRegUnits();
70 if (NumRegUnits != Matrix.size())
71 Queries.reset(new LiveIntervalUnion::Query[NumRegUnits]);
72 Matrix.init(*LIUAlloc, NumRegUnits);
73
74 // Make sure no stale queries get reused.
76}
77
78void LiveRegMatrixWrapperLegacy::releaseMemory() { LRM.releaseMemory(); }
79
80void LiveRegMatrix::releaseMemory() {
81 for (unsigned i = 0, e = Matrix.size(); i != e; ++i) {
82 Matrix[static_cast<MCRegUnit>(i)].clear();
83 // No need to clear Queries here, since LiveIntervalUnion::Query doesn't
84 // have anything important to clear and LiveRegMatrix's runOnFunction()
85 // does a std::unique_ptr::reset anyways.
86 }
87}
88
89template <typename Callable>
91 const LiveInterval &VRegInterval, MCRegister PhysReg,
92 Callable Func) {
93 if (VRegInterval.hasSubRanges()) {
94 for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
95 MCRegUnit Unit = (*Units).first;
96 LaneBitmask Mask = (*Units).second;
97 for (const LiveInterval::SubRange &S : VRegInterval.subranges()) {
98 if ((S.LaneMask & Mask).any()) {
99 if (Func(Unit, S))
100 return true;
101 break;
102 }
103 }
104 }
105 } else {
106 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
107 if (Func(Unit, VRegInterval))
108 return true;
109 }
110 }
111 return false;
112}
113
114void LiveRegMatrix::assign(const LiveInterval &VirtReg, MCRegister PhysReg) {
115 LLVM_DEBUG(dbgs() << "assigning " << printReg(VirtReg.reg(), TRI) << " to "
116 << printReg(PhysReg, TRI) << ':');
117 assert(!VRM->hasPhys(VirtReg.reg()) && "Duplicate VirtReg assignment");
118 VRM->assignVirt2Phys(VirtReg.reg(), PhysReg);
119
121 TRI, VirtReg, PhysReg, [&](MCRegUnit Unit, const LiveRange &Range) {
122 LLVM_DEBUG(dbgs() << ' ' << printRegUnit(Unit, TRI) << ' ' << Range);
123 Matrix[Unit].unify(VirtReg, Range);
124 return false;
125 });
126
127 ++NumAssigned;
128 LLVM_DEBUG(dbgs() << '\n');
129}
130
132 bool ClearAllReferencingSegments) {
133 Register PhysReg = VRM->getPhys(VirtReg.reg());
134 LLVM_DEBUG(dbgs() << "unassigning " << printReg(VirtReg.reg(), TRI)
135 << " from " << printReg(PhysReg, TRI) << ':');
136 VRM->clearVirt(VirtReg.reg());
137
138 if (!ClearAllReferencingSegments) {
139 foreachUnit(TRI, VirtReg, PhysReg,
140 [&](MCRegUnit Unit, const LiveRange &Range) {
141 LLVM_DEBUG(dbgs() << ' ' << printRegUnit(Unit, TRI));
142 Matrix[Unit].extract(VirtReg, Range);
143 return false;
144 });
145 } else {
146 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
147 Matrix[Unit].clearAllSegmentsReferencing(VirtReg);
148 }
149 }
150
151 ++NumUnassigned;
152 LLVM_DEBUG(dbgs() << '\n');
153}
154
156 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
157 if (!Matrix[Unit].empty())
158 return true;
159 }
160 return false;
161}
162
163bool LiveRegMatrix::checkRegMaskInterference(const LiveInterval &VirtReg,
164 MCRegister PhysReg) {
165 // Check if the cached information is valid.
166 // The same BitVector can be reused for all PhysRegs.
167 // We could cache multiple VirtRegs if it becomes necessary.
168 if (RegMaskVirtReg != VirtReg.reg() || RegMaskTag != UserTag) {
169 RegMaskVirtReg = VirtReg.reg();
170 RegMaskTag = UserTag;
171 RegMaskUsable.clear();
172 LIS->checkRegMaskInterference(VirtReg, RegMaskUsable);
173 }
174
175 // The BitVector is indexed by PhysReg, not register unit.
176 // Regmask interference is more fine grained than regunits.
177 // For example, a Win64 call can clobber %ymm8 yet preserve %xmm8.
178 return !RegMaskUsable.empty() &&
179 (!PhysReg || !RegMaskUsable.test(PhysReg.id()));
180}
181
182bool LiveRegMatrix::checkRegUnitInterference(const LiveInterval &VirtReg,
183 MCRegister PhysReg) {
184 if (VirtReg.empty())
185 return false;
186 CoalescerPair CP(VirtReg.reg(), PhysReg, *TRI);
187
188 bool Result = foreachUnit(
189 TRI, VirtReg, PhysReg, [&](MCRegUnit Unit, const LiveRange &Range) {
190 const LiveRange &UnitRange = LIS->getRegUnit(Unit);
191 return Range.overlaps(UnitRange, CP, *LIS->getSlotIndexes());
192 });
193 return Result;
194}
195
196bool LiveRegMatrix::checkRegMaskInterference(SlotIndex Start, SlotIndex End,
197 MCRegister PhysReg) {
200
201 // Find the first regmask slot that is not before Start.
202 auto SlotI = llvm::lower_bound(Slots, Start);
203 for (; SlotI != Slots.end() && *SlotI < End; ++SlotI) {
204 if (MachineOperand::clobbersPhysReg(Bits[SlotI - Slots.begin()], PhysReg))
205 return true;
206 }
207 return false;
208}
209
210bool LiveRegMatrix::checkRegUnitInterference(SlotIndex Start, SlotIndex End,
211 MCRegister PhysReg) {
212 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
213 if (LIS->getRegUnit(Unit).overlaps(Start, End))
214 return true;
215 }
216 return false;
217}
218
220 MCRegUnit RegUnit) {
221 LiveIntervalUnion::Query &Q = Queries[static_cast<unsigned>(RegUnit)];
222 Q.init(UserTag, LR, Matrix[RegUnit]);
223 return Q;
224}
225
228 MCRegister PhysReg) {
229 if (VirtReg.empty())
230 return IK_Free;
231
232 // Regmask interference is the fastest check.
233 if (checkRegMaskInterference(VirtReg, PhysReg))
234 return IK_RegMask;
235
236 // Check for fixed interference.
237 if (checkRegUnitInterference(VirtReg, PhysReg))
238 return IK_RegUnit;
239
240 // Check the matrix for virtual register interference.
241 bool Interference = foreachUnit(TRI, VirtReg, PhysReg,
242 [&](MCRegUnit Unit, const LiveRange &LR) {
243 return query(LR, Unit).checkInterference();
244 });
245 if (Interference)
246 return IK_VirtReg;
247
248 return IK_Free;
249}
250
252 MCRegister PhysReg) {
253 // Regmask interference is the fastest check.
254 if (checkRegMaskInterference(Start, End, PhysReg))
255 return true;
256
257 // Check for fixed interference.
258 if (checkRegUnitInterference(Start, End, PhysReg))
259 return true;
260
261 // Construct artificial live range containing only one segment [Start, End).
262 VNInfo valno(0, Start);
263 LiveRange::Segment Seg(Start, End, &valno);
264 LiveRange LR;
265 LR.addSegment(Seg);
266
267 // Check the matrix for virtual register interference with that segment.
268 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
269 // LR is stack-allocated. LiveRegMatrix caches queries by a key that
270 // includes the address of the live range. If (for the same reg unit) this
271 // checkInterference overload is called twice, without any other query()
272 // calls in between (on heap-allocated LiveRanges) - which would invalidate
273 // the cached query - the LR address seen the second time may well be the
274 // same as that seen the first time, while the Start/End/valno may not - yet
275 // the same cached result would be fetched. To avoid that, we don't cache
276 // this query.
277 //
278 // FIXME: the usability of the Query API needs to be improved to avoid
279 // subtle bugs due to query identity. Avoiding caching, for example, would
280 // greatly simplify things.
282 Q.reset(UserTag, LR, Matrix[Unit]);
283 if (Q.checkInterference())
284 return true;
285 }
286 return false;
287}
288
290 SlotIndex End,
291 MCRegister PhysReg) {
292 // Construct artificial live range containing only one segment [Start, End).
293 VNInfo valno(0, Start);
294 LiveRange::Segment Seg(Start, End, &valno);
295 LiveRange LR;
296 LR.addSegment(Seg);
297
298 LaneBitmask InterferingLanes;
299
300 // Check for interference with that segment
301 for (MCRegUnitMaskIterator MCRU(PhysReg, TRI); MCRU.isValid(); ++MCRU) {
302 auto [Unit, Lanes] = *MCRU;
303 // LR is stack-allocated. LiveRegMatrix caches queries by a key that
304 // includes the address of the live range. If (for the same reg unit) this
305 // checkInterference overload is called twice, without any other query()
306 // calls in between (on heap-allocated LiveRanges) - which would invalidate
307 // the cached query - the LR address seen the second time may well be the
308 // same as that seen the first time, while the Start/End/valno may not - yet
309 // the same cached result would be fetched. To avoid that, we don't cache
310 // this query.
311 //
312 // FIXME: the usability of the Query API needs to be improved to avoid
313 // subtle bugs due to query identity. Avoiding caching, for example, would
314 // greatly simplify things.
316 Q.reset(UserTag, LR, Matrix[Unit]);
317 if (Q.checkInterference())
318 InterferingLanes |= Lanes;
319 }
320
321 return InterferingLanes;
322}
323
324Register LiveRegMatrix::getOneVReg(unsigned PhysReg) const {
325 const LiveInterval *VRegInterval = nullptr;
326 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
327 if ((VRegInterval = Matrix[Unit].getOneVReg()))
328 return VRegInterval->reg();
329 }
330
332}
333
334#ifndef NDEBUG
336 // Build set of all valid LiveInterval pointers from LiveIntervals.
337 DenseSet<const LiveInterval *> ValidIntervals;
338 for (unsigned RegIdx = 0, NumRegs = VRM->getRegInfo().getNumVirtRegs();
339 RegIdx < NumRegs; ++RegIdx) {
340 Register VReg = Register::index2VirtReg(RegIdx);
341 // Only track assigned registers since unassigned ones won't be in Matrix
342 if (VRM->hasPhys(VReg) && LIS->hasInterval(VReg))
343 ValidIntervals.insert(&LIS->getInterval(VReg));
344 }
345
346 // Now scan all LiveIntervalUnions in the matrix and verify each pointer
347 unsigned NumDanglingPointers = 0;
348 for (unsigned I = 0, Size = Matrix.size(); I < Size; ++I) {
349 MCRegUnit Unit = static_cast<MCRegUnit>(I);
350 for (const LiveInterval *LI : Matrix[Unit]) {
351 if (!ValidIntervals.contains(LI)) {
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';
356 }
357 }
358 }
359
360 // Reverse check: every VRM-assigned vreg with a non-empty live interval
361 // must have its segments present in the Matrix for its assigned phys reg.
362 unsigned NumMissing = 0;
363 for (unsigned RegIdx = 0, NumRegs = VRM->getRegInfo().getNumVirtRegs();
364 RegIdx < NumRegs; ++RegIdx) {
365 Register VReg = Register::index2VirtReg(RegIdx);
366 if (!VRM->hasPhys(VReg) || !LIS->hasInterval(VReg))
367 continue;
368 const LiveInterval &LI = LIS->getInterval(VReg);
369 if (LI.empty())
370 continue;
371 MCRegister PhysReg = VRM->getPhys(VReg);
372 // Check that the first segment of LI is present in the LiveUnion for
373 // at least one reg unit of PhysReg.
374 SlotIndex FirstStart = LI.beginIndex();
375 bool Found = false;
376 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
377 auto It = Matrix[Unit].find(FirstStart);
378 if (It.valid() && It.start() == FirstStart && It.value() == &LI) {
379 Found = true;
380 break;
381 }
382 }
383 if (!Found) {
384 ++NumMissing;
385 dbgs() << "ERROR: VirtReg " << printReg(VReg, TRI) << " assigned to "
386 << printReg(PhysReg, TRI)
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)) {
391 dbgs() << " RegUnit " << printRegUnit(Unit, TRI) << " segments: ";
392 auto It = Matrix[Unit].find(FirstStart);
393 if (It.valid())
394 dbgs() << "[" << It.start() << "," << It.stop() << ") -> "
395 << printReg(It.value()->reg(), TRI);
396 else
397 dbgs() << "(none found)";
398 dbgs() << "\n";
399 }
400 }
401 }
402
403 return NumDanglingPointers == 0 && NumMissing == 0;
404}
405#endif
406
407AnalysisKey LiveRegMatrixAnalysis::Key;
408
411 auto &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
412 auto &VRM = MFAM.getResult<VirtRegMapAnalysis>(MF);
413 LiveRegMatrix LRM;
414 LRM.init(MF, LIS, VRM);
415 return LRM;
416}
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.
Live Register Matrix
static bool foreachUnit(const TargetRegisterInfo *TRI, const LiveInterval &VRegInterval, MCRegister PhysReg, Callable Func)
#define I(x, y, z)
Definition MD5.cpp:57
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
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),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:130
iterator begin() const
Definition ArrayRef.h:129
A helper class for register coalescers.
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
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.
Register reg() const
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.
bool empty() const
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...
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.
Definition MCRegister.h:41
static constexpr unsigned NoRegister
Definition MCRegister.h:60
constexpr unsigned id() const
Definition MCRegister.h:82
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.
Definition Register.h:20
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition Register.h:72
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
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)
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 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.
Definition Debug.cpp:209
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2068
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...
Definition Analysis.h:29
This represents a simple continuous liveness interval for a value.