LLVM 22.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/Statistic.h"
24#include "llvm/MC/LaneBitmask.h"
26#include "llvm/Pass.h"
27#include "llvm/Support/Debug.h"
29#include <cassert>
30
31using namespace llvm;
32
33#define DEBUG_TYPE "regalloc"
34
35STATISTIC(NumAssigned , "Number of registers assigned");
36STATISTIC(NumUnassigned , "Number of registers unassigned");
37
40 "Live Register Matrix", false, false)
44 "Live Register Matrix", false, true)
45
47 AU.setPreservesAll();
48 AU.addRequiredTransitive<LiveIntervalsWrapperPass>();
49 AU.addRequiredTransitive<VirtRegMapWrapperLegacy>();
51}
52
54 auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
55 auto &VRM = getAnalysis<VirtRegMapWrapperLegacy>().getVRM();
56 LRM.init(MF, LIS, VRM);
57 return false;
58}
59
61 VirtRegMap &pVRM) {
62 TRI = MF.getSubtarget().getRegisterInfo();
63 LIS = &pLIS;
64 VRM = &pVRM;
65
66 unsigned NumRegUnits = TRI->getNumRegUnits();
67 if (NumRegUnits != Matrix.size())
68 Queries.reset(new LiveIntervalUnion::Query[NumRegUnits]);
69 Matrix.init(*LIUAlloc, NumRegUnits);
70
71 // Make sure no stale queries get reused.
73}
74
75void LiveRegMatrixWrapperLegacy::releaseMemory() { LRM.releaseMemory(); }
76
77void LiveRegMatrix::releaseMemory() {
78 for (unsigned i = 0, e = Matrix.size(); i != e; ++i) {
79 Matrix[i].clear();
80 // No need to clear Queries here, since LiveIntervalUnion::Query doesn't
81 // have anything important to clear and LiveRegMatrix's runOnFunction()
82 // does a std::unique_ptr::reset anyways.
83 }
84}
85
86template <typename Callable>
88 const LiveInterval &VRegInterval, MCRegister PhysReg,
89 Callable Func) {
90 if (VRegInterval.hasSubRanges()) {
91 for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
92 unsigned Unit = (*Units).first;
93 LaneBitmask Mask = (*Units).second;
94 for (const LiveInterval::SubRange &S : VRegInterval.subranges()) {
95 if ((S.LaneMask & Mask).any()) {
96 if (Func(Unit, S))
97 return true;
98 break;
99 }
100 }
101 }
102 } else {
103 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
104 if (Func(Unit, VRegInterval))
105 return true;
106 }
107 }
108 return false;
109}
110
111void LiveRegMatrix::assign(const LiveInterval &VirtReg, MCRegister PhysReg) {
112 LLVM_DEBUG(dbgs() << "assigning " << printReg(VirtReg.reg(), TRI) << " to "
113 << printReg(PhysReg, TRI) << ':');
114 assert(!VRM->hasPhys(VirtReg.reg()) && "Duplicate VirtReg assignment");
115 VRM->assignVirt2Phys(VirtReg.reg(), PhysReg);
116
118 TRI, VirtReg, PhysReg, [&](unsigned Unit, const LiveRange &Range) {
119 LLVM_DEBUG(dbgs() << ' ' << printRegUnit(Unit, TRI) << ' ' << Range);
120 Matrix[Unit].unify(VirtReg, Range);
121 return false;
122 });
123
124 ++NumAssigned;
125 LLVM_DEBUG(dbgs() << '\n');
126}
127
129 Register PhysReg = VRM->getPhys(VirtReg.reg());
130 LLVM_DEBUG(dbgs() << "unassigning " << printReg(VirtReg.reg(), TRI)
131 << " from " << printReg(PhysReg, TRI) << ':');
132 VRM->clearVirt(VirtReg.reg());
133
134 foreachUnit(TRI, VirtReg, PhysReg,
135 [&](unsigned Unit, const LiveRange &Range) {
136 LLVM_DEBUG(dbgs() << ' ' << printRegUnit(Unit, TRI));
137 Matrix[Unit].extract(VirtReg, Range);
138 return false;
139 });
140
141 ++NumUnassigned;
142 LLVM_DEBUG(dbgs() << '\n');
143}
144
146 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
147 if (!Matrix[Unit].empty())
148 return true;
149 }
150 return false;
151}
152
154 MCRegister PhysReg) {
155 // Check if the cached information is valid.
156 // The same BitVector can be reused for all PhysRegs.
157 // We could cache multiple VirtRegs if it becomes necessary.
158 if (RegMaskVirtReg != VirtReg.reg() || RegMaskTag != UserTag) {
159 RegMaskVirtReg = VirtReg.reg();
160 RegMaskTag = UserTag;
161 RegMaskUsable.clear();
162 LIS->checkRegMaskInterference(VirtReg, RegMaskUsable);
163 }
164
165 // The BitVector is indexed by PhysReg, not register unit.
166 // Regmask interference is more fine grained than regunits.
167 // For example, a Win64 call can clobber %ymm8 yet preserve %xmm8.
168 return !RegMaskUsable.empty() &&
169 (!PhysReg || !RegMaskUsable.test(PhysReg.id()));
170}
171
173 MCRegister PhysReg) {
174 if (VirtReg.empty())
175 return false;
176 CoalescerPair CP(VirtReg.reg(), PhysReg, *TRI);
177
178 bool Result = foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit,
179 const LiveRange &Range) {
180 const LiveRange &UnitRange = LIS->getRegUnit(Unit);
181 return Range.overlaps(UnitRange, CP, *LIS->getSlotIndexes());
182 });
183 return Result;
184}
185
187 MCRegUnit RegUnit) {
188 LiveIntervalUnion::Query &Q = Queries[RegUnit];
189 Q.init(UserTag, LR, Matrix[RegUnit]);
190 return Q;
191}
192
195 MCRegister PhysReg) {
196 if (VirtReg.empty())
197 return IK_Free;
198
199 // Regmask interference is the fastest check.
200 if (checkRegMaskInterference(VirtReg, PhysReg))
201 return IK_RegMask;
202
203 // Check for fixed interference.
204 if (checkRegUnitInterference(VirtReg, PhysReg))
205 return IK_RegUnit;
206
207 // Check the matrix for virtual register interference.
208 bool Interference = foreachUnit(TRI, VirtReg, PhysReg,
209 [&](MCRegUnit Unit, const LiveRange &LR) {
210 return query(LR, Unit).checkInterference();
211 });
212 if (Interference)
213 return IK_VirtReg;
214
215 return IK_Free;
216}
217
219 MCRegister PhysReg) {
220 // Construct artificial live range containing only one segment [Start, End).
221 VNInfo valno(0, Start);
222 LiveRange::Segment Seg(Start, End, &valno);
223 LiveRange LR;
224 LR.addSegment(Seg);
225
226 // Check for interference with that segment
227 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
228 // LR is stack-allocated. LiveRegMatrix caches queries by a key that
229 // includes the address of the live range. If (for the same reg unit) this
230 // checkInterference overload is called twice, without any other query()
231 // calls in between (on heap-allocated LiveRanges) - which would invalidate
232 // the cached query - the LR address seen the second time may well be the
233 // same as that seen the first time, while the Start/End/valno may not - yet
234 // the same cached result would be fetched. To avoid that, we don't cache
235 // this query.
236 //
237 // FIXME: the usability of the Query API needs to be improved to avoid
238 // subtle bugs due to query identity. Avoiding caching, for example, would
239 // greatly simplify things.
241 Q.reset(UserTag, LR, Matrix[Unit]);
242 if (Q.checkInterference())
243 return true;
244 }
245 return false;
246}
247
249 SlotIndex End,
250 MCRegister PhysReg) {
251 // Construct artificial live range containing only one segment [Start, End).
252 VNInfo valno(0, Start);
253 LiveRange::Segment Seg(Start, End, &valno);
254 LiveRange LR;
255 LR.addSegment(Seg);
256
257 LaneBitmask InterferingLanes;
258
259 // Check for interference with that segment
260 for (MCRegUnitMaskIterator MCRU(PhysReg, TRI); MCRU.isValid(); ++MCRU) {
261 auto [Unit, Lanes] = *MCRU;
262 // LR is stack-allocated. LiveRegMatrix caches queries by a key that
263 // includes the address of the live range. If (for the same reg unit) this
264 // checkInterference overload is called twice, without any other query()
265 // calls in between (on heap-allocated LiveRanges) - which would invalidate
266 // the cached query - the LR address seen the second time may well be the
267 // same as that seen the first time, while the Start/End/valno may not - yet
268 // the same cached result would be fetched. To avoid that, we don't cache
269 // this query.
270 //
271 // FIXME: the usability of the Query API needs to be improved to avoid
272 // subtle bugs due to query identity. Avoiding caching, for example, would
273 // greatly simplify things.
275 Q.reset(UserTag, LR, Matrix[Unit]);
276 if (Q.checkInterference())
277 InterferingLanes |= Lanes;
278 }
279
280 return InterferingLanes;
281}
282
283Register LiveRegMatrix::getOneVReg(unsigned PhysReg) const {
284 const LiveInterval *VRegInterval = nullptr;
285 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
286 if ((VRegInterval = Matrix[Unit].getOneVReg()))
287 return VRegInterval->reg();
288 }
289
291}
292
293AnalysisKey LiveRegMatrixAnalysis::Key;
294
297 auto &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
298 auto &VRM = MFAM.getResult<VirtRegMapAnalysis>(MF);
299 LiveRegMatrix LRM;
300 LRM.init(MF, LIS, VRM);
301 return LRM;
302}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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)
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:167
#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.
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.
void unassign(const LiveInterval &VirtReg)
Unassign VirtReg from its PhysReg.
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.
@ 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:33
static constexpr unsigned NoRegister
Definition MCRegister.h:52
constexpr unsigned id() const
Definition MCRegister.h:74
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:19
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)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Printable printRegUnit(unsigned 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
unsigned MCRegUnit
Register units are used to compute register aliasing.
Definition MCRegister.h:30
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.