LLVM 22.0.0git
RegAllocBasic.cpp
Go to the documentation of this file.
1//===-- RegAllocBasic.cpp - Basic Register Allocator ----------------------===//
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/// \file
10/// This file defines the RABasic function pass, which provides a minimal
11/// implementation of the basic register allocator.
12///
13//===----------------------------------------------------------------------===//
14
15#include "RegAllocBasic.h"
16#include "AllocationOrder.h"
27#include "llvm/CodeGen/Passes.h"
30#include "llvm/Pass.h"
31#include "llvm/Support/Debug.h"
33
34using namespace llvm;
35
36#define DEBUG_TYPE "regalloc"
37
38static RegisterRegAlloc basicRegAlloc("basic", "basic register allocator",
40
41char RABasic::ID = 0;
42
44
45INITIALIZE_PASS_BEGIN(RABasic, "regallocbasic", "Basic Register Allocator",
46 false, false)
50INITIALIZE_PASS_DEPENDENCY(RegisterCoalescerLegacy)
51INITIALIZE_PASS_DEPENDENCY(MachineSchedulerLegacy)
60 false)
61
62bool RABasic::LRE_CanEraseVirtReg(Register VirtReg) {
63 LiveInterval &LI = LIS->getInterval(VirtReg);
64 if (VRM->hasPhys(VirtReg)) {
65 Matrix->unassign(LI);
66 aboutToRemoveInterval(LI);
67 return true;
68 }
69 // Unassigned virtreg is probably in the priority queue.
70 // RegAllocBase will erase it after dequeueing.
71 // Nonetheless, clear the live-range so that the debug
72 // dump will show the right state for that VirtReg.
73 LI.clear();
74 return false;
75}
76
77void RABasic::LRE_WillShrinkVirtReg(Register VirtReg) {
78 if (!VRM->hasPhys(VirtReg))
79 return;
80
81 // Register is assigned, put it back on the queue for reassignment.
82 LiveInterval &LI = LIS->getInterval(VirtReg);
83 Matrix->unassign(LI);
84 enqueue(&LI);
85}
86
89
91 AU.setPreservesCFG();
114}
115
117 SpillerInstance.reset();
118}
119
120
121// Spill or split all live virtual registers currently unified under PhysReg
122// that interfere with VirtReg. The newly spilled or split live intervals are
123// returned by appending them to SplitVRegs.
125 MCRegister PhysReg,
126 SmallVectorImpl<Register> &SplitVRegs) {
127 // Record each interference and determine if all are spillable before mutating
128 // either the union or live intervals.
130
131 // Collect interferences assigned to any alias of the physical register.
132 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
133 LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, Unit);
134 for (const auto *Intf : reverse(Q.interferingVRegs())) {
135 if (!Intf->isSpillable() || Intf->weight() > VirtReg.weight())
136 return false;
137 Intfs.push_back(Intf);
138 }
139 }
140 LLVM_DEBUG(dbgs() << "spilling " << printReg(PhysReg, TRI)
141 << " interferences with " << VirtReg << "\n");
142 assert(!Intfs.empty() && "expected interference");
143
144 // Spill each interfering vreg allocated to PhysReg or an alias.
145 for (const LiveInterval *Spill : Intfs) {
146 // Skip duplicates.
147 if (!VRM->hasPhys(Spill->reg()))
148 continue;
149
150 // Deallocate the interfering vreg by removing it from the union.
151 // A LiveInterval instance may not be in a union during modification!
152 Matrix->unassign(*Spill);
153
154 // Spill the extracted interval.
155 LiveRangeEdit LRE(Spill, SplitVRegs, *MF, *LIS, VRM, this, &DeadRemats);
156 spiller().spill(LRE);
157 }
158 return true;
159}
160
161// Driver for the register assignment and splitting heuristics.
162// Manages iteration over the LiveIntervalUnions.
163//
164// This is a minimal implementation of register assignment and splitting that
165// spills whenever we run out of registers.
166//
167// selectOrSplit can only be called once per live virtual register. We then do a
168// single interference test for each register the correct class until we find an
169// available register. So, the number of interference tests in the worst case is
170// |vregs| * |machineregs|. And since the number of interference tests is
171// minimal, there is no value in caching them outside the scope of
172// selectOrSplit().
174 SmallVectorImpl<Register> &SplitVRegs) {
175 // Populate a list of physical register spill candidates.
176 SmallVector<MCRegister, 8> PhysRegSpillCands;
177
178 // Check for an available register in this class.
179 auto Order =
181 for (MCRegister PhysReg : Order) {
182 assert(PhysReg.isValid());
183 // Check for interference in PhysReg
184 switch (Matrix->checkInterference(VirtReg, PhysReg)) {
186 // PhysReg is available, allocate it.
187 return PhysReg;
188
190 // Only virtual registers in the way, we may be able to spill them.
191 PhysRegSpillCands.push_back(PhysReg);
192 continue;
193
194 default:
195 // RegMask or RegUnit interference.
196 continue;
197 }
198 }
199
200 // Try to spill another interfering reg with less spill weight.
201 for (MCRegister &PhysReg : PhysRegSpillCands) {
202 if (!spillInterferences(VirtReg, PhysReg, SplitVRegs))
203 continue;
204
205 assert(!Matrix->checkInterference(VirtReg, PhysReg) &&
206 "Interference after spill.");
207 // Tell the caller to allocate to this newly freed physical register.
208 return PhysReg;
209 }
210
211 // No other spill candidates were found, so spill the current VirtReg.
212 LLVM_DEBUG(dbgs() << "spilling: " << VirtReg << '\n');
213 if (!VirtReg.isSpillable())
214 return ~0u;
215 LiveRangeEdit LRE(&VirtReg, SplitVRegs, *MF, *LIS, VRM, this, &DeadRemats);
216 spiller().spill(LRE);
217
218 // The live virtual register requesting allocation was spilled, so tell
219 // the caller not to allocate anything during this round.
220 return 0;
221}
222
224 LLVM_DEBUG(dbgs() << "********** BASIC REGISTER ALLOCATION **********\n"
225 << "********** Function: " << mf.getName() << '\n');
226
227 MF = &mf;
228 auto &MBFI = getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
229 auto &LiveStks = getAnalysis<LiveStacksWrapperLegacy>().getLS();
230 auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
231
232 RegAllocBase::init(getAnalysis<VirtRegMapWrapperLegacy>().getVRM(),
233 getAnalysis<LiveIntervalsWrapperPass>().getLIS(),
234 getAnalysis<LiveRegMatrixWrapperLegacy>().getLRM());
235 VirtRegAuxInfo VRAI(*MF, *LIS, *VRM,
236 getAnalysis<MachineLoopInfoWrapperPass>().getLI(), MBFI,
237 &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI());
239
240 SpillerInstance.reset(
241 createInlineSpiller({*LIS, LiveStks, MDT, MBFI}, *MF, *VRM, VRAI));
242
245
246 // Diagnostic output before rewriting
247 LLVM_DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << *VRM << "\n");
248
250 return true;
251}
252
254 return new RABasic();
255}
256
258 return new RABasic(F);
259}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Live Register Matrix
#define F(x, y, z)
Definition: MD5.cpp:55
#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
regallocbasic
Basic Register Allocator
static RegisterRegAlloc basicRegAlloc("basic", "basic register allocator", createBasicRegisterAllocator)
This file declares the RABasic class, which provides a minimal implementation of the basic register a...
#define LLVM_DEBUG(...)
Definition: Debug.h:119
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
static AllocationOrder create(Register VirtReg, const VirtRegMap &VRM, const RegisterClassInfo &RegClassInfo, const LiveRegMatrix *Matrix)
Create a new AllocationOrder for VirtReg.
Represent the analysis usage information of a pass.
LLVM_ABI AnalysisUsage & addRequiredID(const void *ID)
Definition: Pass.cpp:284
AnalysisUsage & addPreservedID(const void *ID)
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:270
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:314
Query interferences between a single live virtual register and a live interval union.
const SmallVectorImpl< const LiveInterval * > & interferingVRegs(unsigned MaxInterferingRegs=std::numeric_limits< unsigned >::max())
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:690
float weight() const
Definition: LiveInterval.h:722
Register reg() const
Definition: LiveInterval.h:721
bool isSpillable() const
isSpillable - Can this interval be spilled?
Definition: LiveInterval.h:829
LiveInterval & getInterval(Register Reg)
void unassign(const LiveInterval &VirtReg)
Unassign VirtReg from its PhysReg.
LiveIntervalUnion::Query & query(const LiveRange &LR, MCRegUnit RegUnit)
Query a line of the assigned virtual register matrix directly.
@ IK_VirtReg
Virtual register interference.
Definition: LiveRegMatrix.h:91
@ IK_Free
No interference, go ahead and assign.
Definition: LiveRegMatrix.h:86
InterferenceKind checkInterference(const LiveInterval &VirtReg, MCRegister PhysReg)
Check for interference before assigning VirtReg to PhysReg.
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
Analysis pass which computes a MachineDominatorTree.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
RABasic provides a minimal implementation of the basic register allocation algorithm.
Definition: RegAllocBasic.h:39
void getAnalysisUsage(AnalysisUsage &AU) const override
RABasic analysis usage.
MCRegister selectOrSplit(const LiveInterval &VirtReg, SmallVectorImpl< Register > &SplitVRegs) override
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
Spiller & spiller() override
Definition: RegAllocBasic.h:67
RABasic(const RegAllocFilterFunc F=nullptr)
bool runOnMachineFunction(MachineFunction &mf) override
Perform register allocation.
bool spillInterferences(const LiveInterval &VirtReg, MCRegister PhysReg, SmallVectorImpl< Register > &SplitVRegs)
static char ID
RegAllocBase provides the register allocation driver and interface that can be extended to add intere...
Definition: RegAllocBase.h:63
void enqueue(const LiveInterval *LI)
enqueue - Add VirtReg to the priority queue of unassigned registers.
void init(VirtRegMap &vrm, LiveIntervals &lis, LiveRegMatrix &mat)
SmallPtrSet< MachineInstr *, 32 > DeadRemats
Inst which is a def of an original reg and whose defs are already all dead after remat is saved in De...
Definition: RegAllocBase.h:83
const TargetRegisterInfo * TRI
Definition: RegAllocBase.h:67
LiveIntervals * LIS
Definition: RegAllocBase.h:70
LiveRegMatrix * Matrix
Definition: RegAllocBase.h:71
virtual void postOptimization()
VirtRegMap * VRM
Definition: RegAllocBase.h:69
RegisterClassInfo RegClassInfo
Definition: RegAllocBase.h:72
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
bool empty() const
Definition: SmallVector.h:82
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
virtual void spill(LiveRangeEdit &LRE, AllocationOrder *Order=nullptr)=0
spill - Spill the LRE.getParent() live interval.
Calculate auxiliary information for a virtual register such as its spill weight and allocation hint.
void calculateSpillWeightsAndHints()
Compute spill weights and allocation hints for all virtual register live intervals.
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
Definition: VirtRegMap.h:87
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::function< bool(const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, const Register Reg)> RegAllocFilterFunc
Filter function for register classes during regalloc.
LLVM_ABI char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:428
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
LLVM_ABI FunctionPass * createBasicRegisterAllocator()
BasicRegisterAllocation Pass - This pass implements a degenerate global register allocator using the ...
Spiller * createInlineSpiller(const Spiller::RequiredAnalyses &Analyses, MachineFunction &MF, VirtRegMap &VRM, VirtRegAuxInfo &VRAI, LiveRegMatrix *Matrix=nullptr)
Create and return a spiller that will insert spill code directly instead of deferring though VirtRegM...
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.
LLVM_ABI char & RABasicID
Basic register allocator.