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)
59INITIALIZE_PASS_END(RABasic, "regallocbasic", "Basic Register Allocator", false,
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
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;
229 auto &LiveStks = getAnalysis<LiveStacksWrapperLegacy>().getLS();
230 auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
231
235 VirtRegAuxInfo VRAI(*MF, *LIS, *VRM,
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
256
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#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
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:114
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.
float weight() const
Register reg() const
bool isSpillable() const
isSpillable - Can this interval be spilled?
@ IK_VirtReg
Virtual register interference.
@ IK_Free
No interference, go ahead and assign.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:33
Analysis pass which computes a MachineDominatorTree.
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.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
RABasic provides a minimal implementation of the basic register allocation algorithm.
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
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(const RegAllocFilterFunc F=nullptr)
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...
const TargetRegisterInfo * TRI
LiveIntervals * LIS
LiveRegMatrix * Matrix
virtual void postOptimization()
VirtRegMap * VRM
RegisterClassInfo RegClassInfo
Wrapper class representing virtual and physical registers.
Definition Register.h:19
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
This is an optimization pass for GlobalISel generic memory operations.
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:400
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 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.