LLVM 20.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)
45
46void LiveRegMatrixWrapperLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
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() && (!PhysReg || !RegMaskUsable.test(PhysReg));
169}
170
172 MCRegister PhysReg) {
173 if (VirtReg.empty())
174 return false;
175 CoalescerPair CP(VirtReg.reg(), PhysReg, *TRI);
176
177 bool Result = foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit,
178 const LiveRange &Range) {
179 const LiveRange &UnitRange = LIS->getRegUnit(Unit);
180 return Range.overlaps(UnitRange, CP, *LIS->getSlotIndexes());
181 });
182 return Result;
183}
184
186 MCRegister RegUnit) {
187 LiveIntervalUnion::Query &Q = Queries[RegUnit];
188 Q.init(UserTag, LR, Matrix[RegUnit]);
189 return Q;
190}
191
194 MCRegister PhysReg) {
195 if (VirtReg.empty())
196 return IK_Free;
197
198 // Regmask interference is the fastest check.
199 if (checkRegMaskInterference(VirtReg, PhysReg))
200 return IK_RegMask;
201
202 // Check for fixed interference.
203 if (checkRegUnitInterference(VirtReg, PhysReg))
204 return IK_RegUnit;
205
206 // Check the matrix for virtual register interference.
207 bool Interference = foreachUnit(TRI, VirtReg, PhysReg,
208 [&](MCRegister Unit, const LiveRange &LR) {
209 return query(LR, Unit).checkInterference();
210 });
211 if (Interference)
212 return IK_VirtReg;
213
214 return IK_Free;
215}
216
218 MCRegister PhysReg) {
219 // Construct artificial live range containing only one segment [Start, End).
220 VNInfo valno(0, Start);
221 LiveRange::Segment Seg(Start, End, &valno);
222 LiveRange LR;
223 LR.addSegment(Seg);
224
225 // Check for interference with that segment
226 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
227 // LR is stack-allocated. LiveRegMatrix caches queries by a key that
228 // includes the address of the live range. If (for the same reg unit) this
229 // checkInterference overload is called twice, without any other query()
230 // calls in between (on heap-allocated LiveRanges) - which would invalidate
231 // the cached query - the LR address seen the second time may well be the
232 // same as that seen the first time, while the Start/End/valno may not - yet
233 // the same cached result would be fetched. To avoid that, we don't cache
234 // this query.
235 //
236 // FIXME: the usability of the Query API needs to be improved to avoid
237 // subtle bugs due to query identity. Avoiding caching, for example, would
238 // greatly simplify things.
240 Q.reset(UserTag, LR, Matrix[Unit]);
241 if (Q.checkInterference())
242 return true;
243 }
244 return false;
245}
246
249 MCRegister PhysReg) {
250 // Construct artificial live range containing only one segment [Start, End).
251 VNInfo valno(0, Start);
252 LiveRange::Segment Seg(Start, End, &valno);
253 LiveRange LR;
254 LR.addSegment(Seg);
255
256 LaneBitmask InterferingLanes;
257
258 // Check for interference with that segment
259 for (MCRegUnitMaskIterator MCRU(PhysReg, TRI); MCRU.isValid(); ++MCRU) {
260 auto [Unit, Lanes] = *MCRU;
261 // LR is stack-allocated. LiveRegMatrix caches queries by a key that
262 // includes the address of the live range. If (for the same reg unit) this
263 // checkInterference overload is called twice, without any other query()
264 // calls in between (on heap-allocated LiveRanges) - which would invalidate
265 // the cached query - the LR address seen the second time may well be the
266 // same as that seen the first time, while the Start/End/valno may not - yet
267 // the same cached result would be fetched. To avoid that, we don't cache
268 // this query.
269 //
270 // FIXME: the usability of the Query API needs to be improved to avoid
271 // subtle bugs due to query identity. Avoiding caching, for example, would
272 // greatly simplify things.
274 Q.reset(UserTag, LR, Matrix[Unit]);
275 if (Q.checkInterference())
276 InterferingLanes |= Lanes;
277 }
278
279 return InterferingLanes;
280}
281
282Register LiveRegMatrix::getOneVReg(unsigned PhysReg) const {
283 const LiveInterval *VRegInterval = nullptr;
284 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
285 if ((VRegInterval = Matrix[Unit].getOneVReg()))
286 return VRegInterval->reg();
287 }
288
290}
291
292AnalysisKey LiveRegMatrixAnalysis::Key;
293
296 auto &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
297 auto &VRM = MFAM.getResult<VirtRegMapAnalysis>(MF);
298 LiveRegMatrix LRM;
299 LRM.init(MF, LIS, VRM);
300 return LRM;
301}
basic Basic Alias true
Looks at all the uses of the given value Returns the Liveness deduced from the uses of this value Adds all uses that cause the result to be MaybeLive to MaybeLiveRetUses If the result is Live
#define LLVM_DEBUG(...)
Definition: Debug.h:106
bool End
Definition: ELF_riscv.cpp:480
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)
liveregmatrix
unsigned const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:55
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:57
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:52
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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:166
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:410
Represent the analysis usage information of a pass.
bool test(unsigned Idx) const
Definition: BitVector.h:461
void clear()
clear - Removes all bits from the bitvector.
Definition: BitVector.h:335
bool empty() const
empty - Tests whether there are no bits in this bitvector.
Definition: BitVector.h:156
A helper class for register coalescers.
void init(LiveIntervalUnion::Allocator &, unsigned Size)
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.
Definition: LiveInterval.h:694
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:687
Register reg() const
Definition: LiveInterval.h:718
bool hasSubRanges() const
Returns true if subregister liveness information is available.
Definition: LiveInterval.h:810
iterator_range< subrange_iterator > subranges()
Definition: LiveInterval.h:782
bool checkRegMaskInterference(const LiveInterval &LI, BitVector &UsableRegs)
Test if LI is live across any register mask instructions, and compute a bit mask of physical register...
SlotIndexes * getSlotIndexes() const
LiveRange & getRegUnit(unsigned Unit)
Return the live range for register unit Unit.
This class represents the liveness of a register, stack slot, etc.
Definition: LiveInterval.h:157
iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
bool empty() const
Definition: LiveInterval.h:382
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...
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.
LiveIntervalUnion::Query & query(const LiveRange &LR, MCRegister RegUnit)
Query a line of the assigned virtual register matrix directly.
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.
Definition: LiveRegMatrix.h:85
Register getOneVReg(unsigned PhysReg) const
@ IK_VirtReg
Virtual register interference.
Definition: LiveRegMatrix.h:94
@ IK_RegUnit
Register unit interference.
Definition: LiveRegMatrix.h:99
@ IK_Free
No interference, go ahead and assign.
Definition: LiveRegMatrix.h:89
@ 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.
unsigned getNumRegUnits() const
Return the number of (native) register units in the target.
iterator_range< MCRegUnitIterator > regunits(MCRegister Reg) const
Returns an iterator range over all regunits for Reg.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
static constexpr unsigned NoRegister
Definition: MCRegister.h:52
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.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:65
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
VNInfo - Value Number Information.
Definition: LiveInterval.h:53
void clearVirt(Register virtReg)
clears the specified virtual register's, physical register mapping
Definition: VirtRegMap.h:116
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
Definition: VirtRegMap.h:90
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
Definition: VirtRegMap.h:86
void assignVirt2Phys(Register virtReg, MCPhysReg physReg)
creates a mapping for the specified virtual register to the specified physical register
Definition: VirtRegMap.cpp:86
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Printable printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI)
Create Printable object to print register units on a raw_ostream.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
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:28
This represents a simple continuous liveness interval for a value.
Definition: LiveInterval.h:162