LLVM 23.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"
26#include "llvm/MC/LaneBitmask.h"
28#include "llvm/Pass.h"
29#include "llvm/Support/Debug.h"
31#include <cassert>
32
33using namespace llvm;
34
35#define DEBUG_TYPE "regalloc"
36
37STATISTIC(NumAssigned , "Number of registers assigned");
38STATISTIC(NumUnassigned , "Number of registers unassigned");
39
42 "Live Register Matrix", false, false)
46 "Live Register Matrix", false, true)
47
49 AU.setPreservesAll();
50 AU.addRequiredTransitive<LiveIntervalsWrapperPass>();
51 AU.addRequiredTransitive<VirtRegMapWrapperLegacy>();
53}
54
56 auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
57 auto &VRM = getAnalysis<VirtRegMapWrapperLegacy>().getVRM();
58 LRM.init(MF, LIS, VRM);
59 return false;
60}
61
63 VirtRegMap &pVRM) {
64 TRI = MF.getSubtarget().getRegisterInfo();
65 LIS = &pLIS;
66 VRM = &pVRM;
67
68 unsigned NumRegUnits = TRI->getNumRegUnits();
69 if (NumRegUnits != Matrix.size())
70 Queries.reset(new LiveIntervalUnion::Query[NumRegUnits]);
71 Matrix.init(*LIUAlloc, NumRegUnits);
72
73 // Make sure no stale queries get reused.
75}
76
77void LiveRegMatrixWrapperLegacy::releaseMemory() { LRM.releaseMemory(); }
78
79void LiveRegMatrix::releaseMemory() {
80 for (unsigned i = 0, e = Matrix.size(); i != e; ++i) {
81 Matrix[static_cast<MCRegUnit>(i)].clear();
82 // No need to clear Queries here, since LiveIntervalUnion::Query doesn't
83 // have anything important to clear and LiveRegMatrix's runOnFunction()
84 // does a std::unique_ptr::reset anyways.
85 }
86}
87
88template <typename Callable>
90 const LiveInterval &VRegInterval, MCRegister PhysReg,
91 Callable Func) {
92 if (VRegInterval.hasSubRanges()) {
93 for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
94 MCRegUnit Unit = (*Units).first;
95 LaneBitmask Mask = (*Units).second;
96 for (const LiveInterval::SubRange &S : VRegInterval.subranges()) {
97 if ((S.LaneMask & Mask).any()) {
98 if (Func(Unit, S))
99 return true;
100 break;
101 }
102 }
103 }
104 } else {
105 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
106 if (Func(Unit, VRegInterval))
107 return true;
108 }
109 }
110 return false;
111}
112
113void LiveRegMatrix::assign(const LiveInterval &VirtReg, MCRegister PhysReg) {
114 LLVM_DEBUG(dbgs() << "assigning " << printReg(VirtReg.reg(), TRI) << " to "
115 << printReg(PhysReg, TRI) << ':');
116 assert(!VRM->hasPhys(VirtReg.reg()) && "Duplicate VirtReg assignment");
117 VRM->assignVirt2Phys(VirtReg.reg(), PhysReg);
118
120 TRI, VirtReg, PhysReg, [&](MCRegUnit Unit, const LiveRange &Range) {
121 LLVM_DEBUG(dbgs() << ' ' << printRegUnit(Unit, TRI) << ' ' << Range);
122 Matrix[Unit].unify(VirtReg, Range);
123 return false;
124 });
125
126 ++NumAssigned;
127 LLVM_DEBUG(dbgs() << '\n');
128}
129
131 bool ClearAllReferencingSegments) {
132 Register PhysReg = VRM->getPhys(VirtReg.reg());
133 LLVM_DEBUG(dbgs() << "unassigning " << printReg(VirtReg.reg(), TRI)
134 << " from " << printReg(PhysReg, TRI) << ':');
135 VRM->clearVirt(VirtReg.reg());
136
137 if (!ClearAllReferencingSegments) {
138 foreachUnit(TRI, VirtReg, PhysReg,
139 [&](MCRegUnit Unit, const LiveRange &Range) {
140 LLVM_DEBUG(dbgs() << ' ' << printRegUnit(Unit, TRI));
141 Matrix[Unit].extract(VirtReg, Range);
142 return false;
143 });
144 } else {
145 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
146 Matrix[Unit].clearAllSegmentsReferencing(VirtReg);
147 }
148 }
149
150 ++NumUnassigned;
151 LLVM_DEBUG(dbgs() << '\n');
152}
153
155 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
156 if (!Matrix[Unit].empty())
157 return true;
158 }
159 return false;
160}
161
163 MCRegister PhysReg) {
164 // Check if the cached information is valid.
165 // The same BitVector can be reused for all PhysRegs.
166 // We could cache multiple VirtRegs if it becomes necessary.
167 if (RegMaskVirtReg != VirtReg.reg() || RegMaskTag != UserTag) {
168 RegMaskVirtReg = VirtReg.reg();
169 RegMaskTag = UserTag;
170 RegMaskUsable.clear();
171 LIS->checkRegMaskInterference(VirtReg, RegMaskUsable);
172 }
173
174 // The BitVector is indexed by PhysReg, not register unit.
175 // Regmask interference is more fine grained than regunits.
176 // For example, a Win64 call can clobber %ymm8 yet preserve %xmm8.
177 return !RegMaskUsable.empty() &&
178 (!PhysReg || !RegMaskUsable.test(PhysReg.id()));
179}
180
182 MCRegister PhysReg) {
183 if (VirtReg.empty())
184 return false;
185 CoalescerPair CP(VirtReg.reg(), PhysReg, *TRI);
186
187 bool Result = foreachUnit(
188 TRI, VirtReg, PhysReg, [&](MCRegUnit Unit, const LiveRange &Range) {
189 const LiveRange &UnitRange = LIS->getRegUnit(Unit);
190 return Range.overlaps(UnitRange, CP, *LIS->getSlotIndexes());
191 });
192 return Result;
193}
194
196 MCRegUnit RegUnit) {
197 LiveIntervalUnion::Query &Q = Queries[static_cast<unsigned>(RegUnit)];
198 Q.init(UserTag, LR, Matrix[RegUnit]);
199 return Q;
200}
201
204 MCRegister PhysReg) {
205 if (VirtReg.empty())
206 return IK_Free;
207
208 // Regmask interference is the fastest check.
209 if (checkRegMaskInterference(VirtReg, PhysReg))
210 return IK_RegMask;
211
212 // Check for fixed interference.
213 if (checkRegUnitInterference(VirtReg, PhysReg))
214 return IK_RegUnit;
215
216 // Check the matrix for virtual register interference.
217 bool Interference = foreachUnit(TRI, VirtReg, PhysReg,
218 [&](MCRegUnit Unit, const LiveRange &LR) {
219 return query(LR, Unit).checkInterference();
220 });
221 if (Interference)
222 return IK_VirtReg;
223
224 return IK_Free;
225}
226
228 MCRegister PhysReg) {
229 // Construct artificial live range containing only one segment [Start, End).
230 VNInfo valno(0, Start);
231 LiveRange::Segment Seg(Start, End, &valno);
232 LiveRange LR;
233 LR.addSegment(Seg);
234
235 // Check for interference with that segment
236 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
237 // LR is stack-allocated. LiveRegMatrix caches queries by a key that
238 // includes the address of the live range. If (for the same reg unit) this
239 // checkInterference overload is called twice, without any other query()
240 // calls in between (on heap-allocated LiveRanges) - which would invalidate
241 // the cached query - the LR address seen the second time may well be the
242 // same as that seen the first time, while the Start/End/valno may not - yet
243 // the same cached result would be fetched. To avoid that, we don't cache
244 // this query.
245 //
246 // FIXME: the usability of the Query API needs to be improved to avoid
247 // subtle bugs due to query identity. Avoiding caching, for example, would
248 // greatly simplify things.
250 Q.reset(UserTag, LR, Matrix[Unit]);
251 if (Q.checkInterference())
252 return true;
253 }
254 return false;
255}
256
258 SlotIndex End,
259 MCRegister PhysReg) {
260 // Construct artificial live range containing only one segment [Start, End).
261 VNInfo valno(0, Start);
262 LiveRange::Segment Seg(Start, End, &valno);
263 LiveRange LR;
264 LR.addSegment(Seg);
265
266 LaneBitmask InterferingLanes;
267
268 // Check for interference with that segment
269 for (MCRegUnitMaskIterator MCRU(PhysReg, TRI); MCRU.isValid(); ++MCRU) {
270 auto [Unit, Lanes] = *MCRU;
271 // LR is stack-allocated. LiveRegMatrix caches queries by a key that
272 // includes the address of the live range. If (for the same reg unit) this
273 // checkInterference overload is called twice, without any other query()
274 // calls in between (on heap-allocated LiveRanges) - which would invalidate
275 // the cached query - the LR address seen the second time may well be the
276 // same as that seen the first time, while the Start/End/valno may not - yet
277 // the same cached result would be fetched. To avoid that, we don't cache
278 // this query.
279 //
280 // FIXME: the usability of the Query API needs to be improved to avoid
281 // subtle bugs due to query identity. Avoiding caching, for example, would
282 // greatly simplify things.
284 Q.reset(UserTag, LR, Matrix[Unit]);
285 if (Q.checkInterference())
286 InterferingLanes |= Lanes;
287 }
288
289 return InterferingLanes;
290}
291
292Register LiveRegMatrix::getOneVReg(unsigned PhysReg) const {
293 const LiveInterval *VRegInterval = nullptr;
294 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
295 if ((VRegInterval = Matrix[Unit].getOneVReg()))
296 return VRegInterval->reg();
297 }
298
300}
301
302#ifndef NDEBUG
304 // Build set of all valid LiveInterval pointers from LiveIntervals.
305 DenseSet<const LiveInterval *> ValidIntervals;
306 for (unsigned RegIdx = 0, NumRegs = VRM->getRegInfo().getNumVirtRegs();
307 RegIdx < NumRegs; ++RegIdx) {
308 Register VReg = Register::index2VirtReg(RegIdx);
309 // Only track assigned registers since unassigned ones won't be in Matrix
310 if (VRM->hasPhys(VReg) && LIS->hasInterval(VReg))
311 ValidIntervals.insert(&LIS->getInterval(VReg));
312 }
313
314 // Now scan all LiveIntervalUnions in the matrix and verify each pointer
315 unsigned NumDanglingPointers = 0;
316 for (unsigned I = 0, Size = Matrix.size(); I < Size; ++I) {
317 MCRegUnit Unit = static_cast<MCRegUnit>(I);
318 for (const LiveInterval *LI : Matrix[Unit]) {
319 if (!ValidIntervals.contains(LI)) {
320 ++NumDanglingPointers;
321 dbgs() << "ERROR: LiveInterval pointer is not found in LiveIntervals:\n"
322 << " Register Unit: " << printRegUnit(Unit, TRI) << '\n'
323 << " LiveInterval pointer: " << LI << '\n';
324 }
325 }
326 }
327 return NumDanglingPointers == 0;
328}
329#endif
330
331AnalysisKey LiveRegMatrixAnalysis::Key;
332
335 auto &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
336 auto &VRM = MFAM.getResult<VirtRegMapAnalysis>(MF);
337 LiveRegMatrix LRM;
338 LRM.init(MF, LIS, VRM);
339 return LRM;
340}
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:114
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.
A helper class for register coalescers.
Implements a dense probed hash-table based set.
Definition DenseSet.h:279
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()
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
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...
bool checkRegMaskInterference(const LiveInterval &VirtReg, MCRegister PhysReg=MCRegister::NoRegister)
Check for regmask interference only.
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.
Register getOneVReg(unsigned PhysReg) const
LiveIntervalUnion::Query & query(const LiveRange &LR, MCRegUnit RegUnit)
Query a line of the assigned virtual register matrix directly.
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.
void init(MachineFunction &MF, LiveIntervals &LIS, VirtRegMap &VRM)
void assign(const LiveInterval &VirtReg, MCRegister PhysReg)
Assign VirtReg to PhysReg.
InterferenceKind checkInterference(const LiveInterval &VirtReg, MCRegister PhysReg)
Check for interference before assigning VirtReg to PhysReg.
bool checkRegUnitInterference(const LiveInterval &VirtReg, MCRegister PhysReg)
Check for regunit interference only.
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.
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:202
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:175
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
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:207
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.