1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceRegAlloc.cpp - Linear-scan implementation -----------===//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // The Subzero Code Generator
4*03ce13f7SAndroid Build Coastguard Worker //
5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*03ce13f7SAndroid Build Coastguard Worker //
8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*03ce13f7SAndroid Build Coastguard Worker ///
10*03ce13f7SAndroid Build Coastguard Worker /// \file
11*03ce13f7SAndroid Build Coastguard Worker /// \brief Implements the LinearScan class, which performs the linear-scan
12*03ce13f7SAndroid Build Coastguard Worker /// register allocation after liveness analysis has been performed.
13*03ce13f7SAndroid Build Coastguard Worker ///
14*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*03ce13f7SAndroid Build Coastguard Worker
16*03ce13f7SAndroid Build Coastguard Worker #include "IceRegAlloc.h"
17*03ce13f7SAndroid Build Coastguard Worker
18*03ce13f7SAndroid Build Coastguard Worker #include "IceBitVector.h"
19*03ce13f7SAndroid Build Coastguard Worker #include "IceCfg.h"
20*03ce13f7SAndroid Build Coastguard Worker #include "IceCfgNode.h"
21*03ce13f7SAndroid Build Coastguard Worker #include "IceInst.h"
22*03ce13f7SAndroid Build Coastguard Worker #include "IceInstVarIter.h"
23*03ce13f7SAndroid Build Coastguard Worker #include "IceOperand.h"
24*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLowering.h"
25*03ce13f7SAndroid Build Coastguard Worker
26*03ce13f7SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
27*03ce13f7SAndroid Build Coastguard Worker
28*03ce13f7SAndroid Build Coastguard Worker namespace Ice {
29*03ce13f7SAndroid Build Coastguard Worker
30*03ce13f7SAndroid Build Coastguard Worker namespace {
31*03ce13f7SAndroid Build Coastguard Worker
32*03ce13f7SAndroid Build Coastguard Worker // Returns true if Var has any definitions within Item's live range.
33*03ce13f7SAndroid Build Coastguard Worker // TODO(stichnot): Consider trimming the Definitions list similar to how the
34*03ce13f7SAndroid Build Coastguard Worker // live ranges are trimmed, since all the overlapsDefs() tests are whether some
35*03ce13f7SAndroid Build Coastguard Worker // variable's definitions overlap Cur, and trimming is with respect Cur.start.
36*03ce13f7SAndroid Build Coastguard Worker // Initial tests show no measurable performance difference, so we'll keep the
37*03ce13f7SAndroid Build Coastguard Worker // code simple for now.
overlapsDefs(const Cfg * Func,const Variable * Item,const Variable * Var)38*03ce13f7SAndroid Build Coastguard Worker bool overlapsDefs(const Cfg *Func, const Variable *Item, const Variable *Var) {
39*03ce13f7SAndroid Build Coastguard Worker constexpr bool UseTrimmed = true;
40*03ce13f7SAndroid Build Coastguard Worker VariablesMetadata *VMetadata = Func->getVMetadata();
41*03ce13f7SAndroid Build Coastguard Worker if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var))
42*03ce13f7SAndroid Build Coastguard Worker if (Item->getLiveRange().overlapsInst(FirstDef->getNumber(), UseTrimmed))
43*03ce13f7SAndroid Build Coastguard Worker return true;
44*03ce13f7SAndroid Build Coastguard Worker for (const Inst *Def : VMetadata->getLatterDefinitions(Var)) {
45*03ce13f7SAndroid Build Coastguard Worker if (Item->getLiveRange().overlapsInst(Def->getNumber(), UseTrimmed))
46*03ce13f7SAndroid Build Coastguard Worker return true;
47*03ce13f7SAndroid Build Coastguard Worker }
48*03ce13f7SAndroid Build Coastguard Worker return false;
49*03ce13f7SAndroid Build Coastguard Worker }
50*03ce13f7SAndroid Build Coastguard Worker
dumpDisableOverlap(const Cfg * Func,const Variable * Var,const char * Reason)51*03ce13f7SAndroid Build Coastguard Worker void dumpDisableOverlap(const Cfg *Func, const Variable *Var,
52*03ce13f7SAndroid Build Coastguard Worker const char *Reason) {
53*03ce13f7SAndroid Build Coastguard Worker if (!BuildDefs::dump())
54*03ce13f7SAndroid Build Coastguard Worker return;
55*03ce13f7SAndroid Build Coastguard Worker if (!Func->isVerbose(IceV_LinearScan))
56*03ce13f7SAndroid Build Coastguard Worker return;
57*03ce13f7SAndroid Build Coastguard Worker
58*03ce13f7SAndroid Build Coastguard Worker VariablesMetadata *VMetadata = Func->getVMetadata();
59*03ce13f7SAndroid Build Coastguard Worker Ostream &Str = Func->getContext()->getStrDump();
60*03ce13f7SAndroid Build Coastguard Worker Str << "Disabling Overlap due to " << Reason << " " << *Var
61*03ce13f7SAndroid Build Coastguard Worker << " LIVE=" << Var->getLiveRange() << " Defs=";
62*03ce13f7SAndroid Build Coastguard Worker if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var))
63*03ce13f7SAndroid Build Coastguard Worker Str << FirstDef->getNumber();
64*03ce13f7SAndroid Build Coastguard Worker const InstDefList &Defs = VMetadata->getLatterDefinitions(Var);
65*03ce13f7SAndroid Build Coastguard Worker for (size_t i = 0; i < Defs.size(); ++i) {
66*03ce13f7SAndroid Build Coastguard Worker Str << "," << Defs[i]->getNumber();
67*03ce13f7SAndroid Build Coastguard Worker }
68*03ce13f7SAndroid Build Coastguard Worker Str << "\n";
69*03ce13f7SAndroid Build Coastguard Worker }
70*03ce13f7SAndroid Build Coastguard Worker
dumpLiveRange(const Variable * Var,const Cfg * Func)71*03ce13f7SAndroid Build Coastguard Worker void dumpLiveRange(const Variable *Var, const Cfg *Func) {
72*03ce13f7SAndroid Build Coastguard Worker if (!BuildDefs::dump())
73*03ce13f7SAndroid Build Coastguard Worker return;
74*03ce13f7SAndroid Build Coastguard Worker Ostream &Str = Func->getContext()->getStrDump();
75*03ce13f7SAndroid Build Coastguard Worker Str << "R=";
76*03ce13f7SAndroid Build Coastguard Worker if (Var->hasRegTmp()) {
77*03ce13f7SAndroid Build Coastguard Worker Str << llvm::format("%2d", int(Var->getRegNumTmp()));
78*03ce13f7SAndroid Build Coastguard Worker } else {
79*03ce13f7SAndroid Build Coastguard Worker Str << "NA";
80*03ce13f7SAndroid Build Coastguard Worker }
81*03ce13f7SAndroid Build Coastguard Worker Str << " V=";
82*03ce13f7SAndroid Build Coastguard Worker Var->dump(Func);
83*03ce13f7SAndroid Build Coastguard Worker Str << " Range=" << Var->getLiveRange();
84*03ce13f7SAndroid Build Coastguard Worker }
85*03ce13f7SAndroid Build Coastguard Worker
findMinWeightIndex(const SmallBitVector & RegMask,const llvm::SmallVector<RegWeight,LinearScan::REGS_SIZE> & Weights)86*03ce13f7SAndroid Build Coastguard Worker int32_t findMinWeightIndex(
87*03ce13f7SAndroid Build Coastguard Worker const SmallBitVector &RegMask,
88*03ce13f7SAndroid Build Coastguard Worker const llvm::SmallVector<RegWeight, LinearScan::REGS_SIZE> &Weights) {
89*03ce13f7SAndroid Build Coastguard Worker int MinWeightIndex = -1;
90*03ce13f7SAndroid Build Coastguard Worker for (RegNumT i : RegNumBVIter(RegMask)) {
91*03ce13f7SAndroid Build Coastguard Worker if (MinWeightIndex < 0 || Weights[i] < Weights[MinWeightIndex])
92*03ce13f7SAndroid Build Coastguard Worker MinWeightIndex = i;
93*03ce13f7SAndroid Build Coastguard Worker }
94*03ce13f7SAndroid Build Coastguard Worker assert(getFlags().getRegAllocReserve() || MinWeightIndex >= 0);
95*03ce13f7SAndroid Build Coastguard Worker return MinWeightIndex;
96*03ce13f7SAndroid Build Coastguard Worker }
97*03ce13f7SAndroid Build Coastguard Worker
98*03ce13f7SAndroid Build Coastguard Worker } // end of anonymous namespace
99*03ce13f7SAndroid Build Coastguard Worker
LinearScan(Cfg * Func)100*03ce13f7SAndroid Build Coastguard Worker LinearScan::LinearScan(Cfg *Func)
101*03ce13f7SAndroid Build Coastguard Worker : Func(Func), Ctx(Func->getContext()), Target(Func->getTarget()),
102*03ce13f7SAndroid Build Coastguard Worker Verbose(BuildDefs::dump() && Func->isVerbose(IceV_LinearScan)),
103*03ce13f7SAndroid Build Coastguard Worker UseReserve(getFlags().getRegAllocReserve()) {}
104*03ce13f7SAndroid Build Coastguard Worker
105*03ce13f7SAndroid Build Coastguard Worker // Prepare for full register allocation of all variables. We depend on liveness
106*03ce13f7SAndroid Build Coastguard Worker // analysis to have calculated live ranges.
initForGlobal()107*03ce13f7SAndroid Build Coastguard Worker void LinearScan::initForGlobal() {
108*03ce13f7SAndroid Build Coastguard Worker TimerMarker T(TimerStack::TT_initUnhandled, Func);
109*03ce13f7SAndroid Build Coastguard Worker FindPreference = true;
110*03ce13f7SAndroid Build Coastguard Worker // For full register allocation, normally we want to enable FindOverlap
111*03ce13f7SAndroid Build Coastguard Worker // (meaning we look for opportunities for two overlapping live ranges to
112*03ce13f7SAndroid Build Coastguard Worker // safely share the same register). However, we disable it for phi-lowering
113*03ce13f7SAndroid Build Coastguard Worker // register allocation since no overlap opportunities should be available and
114*03ce13f7SAndroid Build Coastguard Worker // it's more expensive to look for opportunities.
115*03ce13f7SAndroid Build Coastguard Worker FindOverlap = (Kind != RAK_Phi);
116*03ce13f7SAndroid Build Coastguard Worker Unhandled.reserve(Vars.size());
117*03ce13f7SAndroid Build Coastguard Worker UnhandledPrecolored.reserve(Vars.size());
118*03ce13f7SAndroid Build Coastguard Worker // Gather the live ranges of all variables and add them to the Unhandled set.
119*03ce13f7SAndroid Build Coastguard Worker for (Variable *Var : Vars) {
120*03ce13f7SAndroid Build Coastguard Worker // Don't consider rematerializable variables.
121*03ce13f7SAndroid Build Coastguard Worker if (Var->isRematerializable())
122*03ce13f7SAndroid Build Coastguard Worker continue;
123*03ce13f7SAndroid Build Coastguard Worker // Explicitly don't consider zero-weight variables, which are meant to be
124*03ce13f7SAndroid Build Coastguard Worker // spill slots.
125*03ce13f7SAndroid Build Coastguard Worker if (Var->mustNotHaveReg())
126*03ce13f7SAndroid Build Coastguard Worker continue;
127*03ce13f7SAndroid Build Coastguard Worker // Don't bother if the variable has a null live range, which means it was
128*03ce13f7SAndroid Build Coastguard Worker // never referenced.
129*03ce13f7SAndroid Build Coastguard Worker if (Var->getLiveRange().isEmpty())
130*03ce13f7SAndroid Build Coastguard Worker continue;
131*03ce13f7SAndroid Build Coastguard Worker Var->untrimLiveRange();
132*03ce13f7SAndroid Build Coastguard Worker Unhandled.push_back(Var);
133*03ce13f7SAndroid Build Coastguard Worker if (Var->hasReg()) {
134*03ce13f7SAndroid Build Coastguard Worker Var->setRegNumTmp(Var->getRegNum());
135*03ce13f7SAndroid Build Coastguard Worker Var->setMustHaveReg();
136*03ce13f7SAndroid Build Coastguard Worker UnhandledPrecolored.push_back(Var);
137*03ce13f7SAndroid Build Coastguard Worker }
138*03ce13f7SAndroid Build Coastguard Worker }
139*03ce13f7SAndroid Build Coastguard Worker
140*03ce13f7SAndroid Build Coastguard Worker // Build the (ordered) list of FakeKill instruction numbers.
141*03ce13f7SAndroid Build Coastguard Worker Kills.clear();
142*03ce13f7SAndroid Build Coastguard Worker // Phi lowering should not be creating new call instructions, so there should
143*03ce13f7SAndroid Build Coastguard Worker // be no infinite-weight not-yet-colored live ranges that span a call
144*03ce13f7SAndroid Build Coastguard Worker // instruction, hence no need to construct the Kills list.
145*03ce13f7SAndroid Build Coastguard Worker if (Kind == RAK_Phi)
146*03ce13f7SAndroid Build Coastguard Worker return;
147*03ce13f7SAndroid Build Coastguard Worker for (CfgNode *Node : Func->getNodes()) {
148*03ce13f7SAndroid Build Coastguard Worker for (Inst &I : Node->getInsts()) {
149*03ce13f7SAndroid Build Coastguard Worker if (auto *Kill = llvm::dyn_cast<InstFakeKill>(&I)) {
150*03ce13f7SAndroid Build Coastguard Worker if (!Kill->isDeleted() && !Kill->getLinked()->isDeleted())
151*03ce13f7SAndroid Build Coastguard Worker Kills.push_back(I.getNumber());
152*03ce13f7SAndroid Build Coastguard Worker }
153*03ce13f7SAndroid Build Coastguard Worker }
154*03ce13f7SAndroid Build Coastguard Worker }
155*03ce13f7SAndroid Build Coastguard Worker }
156*03ce13f7SAndroid Build Coastguard Worker
157*03ce13f7SAndroid Build Coastguard Worker // Validate the integrity of the live ranges. If there are any errors, it
158*03ce13f7SAndroid Build Coastguard Worker // prints details and returns false. On success, it returns true.
livenessValidateIntervals(const DefUseErrorList & DefsWithoutUses,const DefUseErrorList & UsesBeforeDefs,const CfgVector<InstNumberT> & LRBegin,const CfgVector<InstNumberT> & LREnd) const159*03ce13f7SAndroid Build Coastguard Worker bool LinearScan::livenessValidateIntervals(
160*03ce13f7SAndroid Build Coastguard Worker const DefUseErrorList &DefsWithoutUses,
161*03ce13f7SAndroid Build Coastguard Worker const DefUseErrorList &UsesBeforeDefs,
162*03ce13f7SAndroid Build Coastguard Worker const CfgVector<InstNumberT> &LRBegin,
163*03ce13f7SAndroid Build Coastguard Worker const CfgVector<InstNumberT> &LREnd) const {
164*03ce13f7SAndroid Build Coastguard Worker if (DefsWithoutUses.empty() && UsesBeforeDefs.empty())
165*03ce13f7SAndroid Build Coastguard Worker return true;
166*03ce13f7SAndroid Build Coastguard Worker
167*03ce13f7SAndroid Build Coastguard Worker if (!BuildDefs::dump())
168*03ce13f7SAndroid Build Coastguard Worker return false;
169*03ce13f7SAndroid Build Coastguard Worker
170*03ce13f7SAndroid Build Coastguard Worker OstreamLocker L(Ctx);
171*03ce13f7SAndroid Build Coastguard Worker Ostream &Str = Ctx->getStrDump();
172*03ce13f7SAndroid Build Coastguard Worker for (SizeT VarNum : DefsWithoutUses) {
173*03ce13f7SAndroid Build Coastguard Worker Variable *Var = Vars[VarNum];
174*03ce13f7SAndroid Build Coastguard Worker Str << "LR def without use, instruction " << LRBegin[VarNum]
175*03ce13f7SAndroid Build Coastguard Worker << ", variable " << Var->getName() << "\n";
176*03ce13f7SAndroid Build Coastguard Worker }
177*03ce13f7SAndroid Build Coastguard Worker for (SizeT VarNum : UsesBeforeDefs) {
178*03ce13f7SAndroid Build Coastguard Worker Variable *Var = Vars[VarNum];
179*03ce13f7SAndroid Build Coastguard Worker Str << "LR use before def, instruction " << LREnd[VarNum] << ", variable "
180*03ce13f7SAndroid Build Coastguard Worker << Var->getName() << "\n";
181*03ce13f7SAndroid Build Coastguard Worker }
182*03ce13f7SAndroid Build Coastguard Worker return false;
183*03ce13f7SAndroid Build Coastguard Worker }
184*03ce13f7SAndroid Build Coastguard Worker
185*03ce13f7SAndroid Build Coastguard Worker // Prepare for very simple register allocation of only infinite-weight Variables
186*03ce13f7SAndroid Build Coastguard Worker // while respecting pre-colored Variables. Some properties we take advantage of:
187*03ce13f7SAndroid Build Coastguard Worker //
188*03ce13f7SAndroid Build Coastguard Worker // * Live ranges of interest consist of a single segment.
189*03ce13f7SAndroid Build Coastguard Worker //
190*03ce13f7SAndroid Build Coastguard Worker // * Live ranges of interest never span a call instruction.
191*03ce13f7SAndroid Build Coastguard Worker //
192*03ce13f7SAndroid Build Coastguard Worker // * Phi instructions are not considered because either phis have already been
193*03ce13f7SAndroid Build Coastguard Worker // lowered, or they don't contain any pre-colored or infinite-weight
194*03ce13f7SAndroid Build Coastguard Worker // Variables.
195*03ce13f7SAndroid Build Coastguard Worker //
196*03ce13f7SAndroid Build Coastguard Worker // * We don't need to renumber instructions before computing live ranges because
197*03ce13f7SAndroid Build Coastguard Worker // all the high-level ICE instructions are deleted prior to lowering, and the
198*03ce13f7SAndroid Build Coastguard Worker // low-level instructions are added in monotonically increasing order.
199*03ce13f7SAndroid Build Coastguard Worker //
200*03ce13f7SAndroid Build Coastguard Worker // * There are no opportunities for register preference or allowing overlap.
201*03ce13f7SAndroid Build Coastguard Worker //
202*03ce13f7SAndroid Build Coastguard Worker // Some properties we aren't (yet) taking advantage of:
203*03ce13f7SAndroid Build Coastguard Worker //
204*03ce13f7SAndroid Build Coastguard Worker // * Because live ranges are a single segment, the Inactive set will always be
205*03ce13f7SAndroid Build Coastguard Worker // empty, and the live range trimming operation is unnecessary.
206*03ce13f7SAndroid Build Coastguard Worker //
207*03ce13f7SAndroid Build Coastguard Worker // * Calculating overlap of single-segment live ranges could be optimized a bit.
initForInfOnly()208*03ce13f7SAndroid Build Coastguard Worker void LinearScan::initForInfOnly() {
209*03ce13f7SAndroid Build Coastguard Worker TimerMarker T(TimerStack::TT_initUnhandled, Func);
210*03ce13f7SAndroid Build Coastguard Worker FindPreference = false;
211*03ce13f7SAndroid Build Coastguard Worker FindOverlap = false;
212*03ce13f7SAndroid Build Coastguard Worker SizeT NumVars = 0;
213*03ce13f7SAndroid Build Coastguard Worker
214*03ce13f7SAndroid Build Coastguard Worker // Iterate across all instructions and record the begin and end of the live
215*03ce13f7SAndroid Build Coastguard Worker // range for each variable that is pre-colored or infinite weight.
216*03ce13f7SAndroid Build Coastguard Worker CfgVector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel);
217*03ce13f7SAndroid Build Coastguard Worker CfgVector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel);
218*03ce13f7SAndroid Build Coastguard Worker DefUseErrorList DefsWithoutUses, UsesBeforeDefs;
219*03ce13f7SAndroid Build Coastguard Worker for (CfgNode *Node : Func->getNodes()) {
220*03ce13f7SAndroid Build Coastguard Worker for (Inst &Instr : Node->getInsts()) {
221*03ce13f7SAndroid Build Coastguard Worker if (Instr.isDeleted())
222*03ce13f7SAndroid Build Coastguard Worker continue;
223*03ce13f7SAndroid Build Coastguard Worker FOREACH_VAR_IN_INST(Var, Instr) {
224*03ce13f7SAndroid Build Coastguard Worker if (Var->getIgnoreLiveness())
225*03ce13f7SAndroid Build Coastguard Worker continue;
226*03ce13f7SAndroid Build Coastguard Worker if (Var->hasReg() || Var->mustHaveReg()) {
227*03ce13f7SAndroid Build Coastguard Worker SizeT VarNum = Var->getIndex();
228*03ce13f7SAndroid Build Coastguard Worker LREnd[VarNum] = Instr.getNumber();
229*03ce13f7SAndroid Build Coastguard Worker if (!Var->getIsArg() && LRBegin[VarNum] == Inst::NumberSentinel)
230*03ce13f7SAndroid Build Coastguard Worker UsesBeforeDefs.push_back(VarNum);
231*03ce13f7SAndroid Build Coastguard Worker }
232*03ce13f7SAndroid Build Coastguard Worker }
233*03ce13f7SAndroid Build Coastguard Worker if (const Variable *Var = Instr.getDest()) {
234*03ce13f7SAndroid Build Coastguard Worker if (!Var->getIgnoreLiveness() &&
235*03ce13f7SAndroid Build Coastguard Worker (Var->hasReg() || Var->mustHaveReg())) {
236*03ce13f7SAndroid Build Coastguard Worker if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) {
237*03ce13f7SAndroid Build Coastguard Worker LRBegin[Var->getIndex()] = Instr.getNumber();
238*03ce13f7SAndroid Build Coastguard Worker ++NumVars;
239*03ce13f7SAndroid Build Coastguard Worker }
240*03ce13f7SAndroid Build Coastguard Worker }
241*03ce13f7SAndroid Build Coastguard Worker }
242*03ce13f7SAndroid Build Coastguard Worker }
243*03ce13f7SAndroid Build Coastguard Worker }
244*03ce13f7SAndroid Build Coastguard Worker
245*03ce13f7SAndroid Build Coastguard Worker Unhandled.reserve(NumVars);
246*03ce13f7SAndroid Build Coastguard Worker UnhandledPrecolored.reserve(NumVars);
247*03ce13f7SAndroid Build Coastguard Worker for (SizeT i = 0; i < Vars.size(); ++i) {
248*03ce13f7SAndroid Build Coastguard Worker Variable *Var = Vars[i];
249*03ce13f7SAndroid Build Coastguard Worker if (Var->isRematerializable())
250*03ce13f7SAndroid Build Coastguard Worker continue;
251*03ce13f7SAndroid Build Coastguard Worker if (LRBegin[i] != Inst::NumberSentinel) {
252*03ce13f7SAndroid Build Coastguard Worker if (LREnd[i] == Inst::NumberSentinel) {
253*03ce13f7SAndroid Build Coastguard Worker DefsWithoutUses.push_back(i);
254*03ce13f7SAndroid Build Coastguard Worker continue;
255*03ce13f7SAndroid Build Coastguard Worker }
256*03ce13f7SAndroid Build Coastguard Worker Unhandled.push_back(Var);
257*03ce13f7SAndroid Build Coastguard Worker Var->resetLiveRange();
258*03ce13f7SAndroid Build Coastguard Worker Var->addLiveRange(LRBegin[i], LREnd[i]);
259*03ce13f7SAndroid Build Coastguard Worker Var->untrimLiveRange();
260*03ce13f7SAndroid Build Coastguard Worker if (Var->hasReg()) {
261*03ce13f7SAndroid Build Coastguard Worker Var->setRegNumTmp(Var->getRegNum());
262*03ce13f7SAndroid Build Coastguard Worker Var->setMustHaveReg();
263*03ce13f7SAndroid Build Coastguard Worker UnhandledPrecolored.push_back(Var);
264*03ce13f7SAndroid Build Coastguard Worker }
265*03ce13f7SAndroid Build Coastguard Worker --NumVars;
266*03ce13f7SAndroid Build Coastguard Worker }
267*03ce13f7SAndroid Build Coastguard Worker }
268*03ce13f7SAndroid Build Coastguard Worker
269*03ce13f7SAndroid Build Coastguard Worker if (!livenessValidateIntervals(DefsWithoutUses, UsesBeforeDefs, LRBegin,
270*03ce13f7SAndroid Build Coastguard Worker LREnd)) {
271*03ce13f7SAndroid Build Coastguard Worker llvm::report_fatal_error("initForInfOnly: Liveness error");
272*03ce13f7SAndroid Build Coastguard Worker return;
273*03ce13f7SAndroid Build Coastguard Worker }
274*03ce13f7SAndroid Build Coastguard Worker
275*03ce13f7SAndroid Build Coastguard Worker if (!DefsWithoutUses.empty() || !UsesBeforeDefs.empty()) {
276*03ce13f7SAndroid Build Coastguard Worker if (BuildDefs::dump()) {
277*03ce13f7SAndroid Build Coastguard Worker OstreamLocker L(Ctx);
278*03ce13f7SAndroid Build Coastguard Worker Ostream &Str = Ctx->getStrDump();
279*03ce13f7SAndroid Build Coastguard Worker for (SizeT VarNum : DefsWithoutUses) {
280*03ce13f7SAndroid Build Coastguard Worker Variable *Var = Vars[VarNum];
281*03ce13f7SAndroid Build Coastguard Worker Str << "LR def without use, instruction " << LRBegin[VarNum]
282*03ce13f7SAndroid Build Coastguard Worker << ", variable " << Var->getName() << "\n";
283*03ce13f7SAndroid Build Coastguard Worker }
284*03ce13f7SAndroid Build Coastguard Worker for (SizeT VarNum : UsesBeforeDefs) {
285*03ce13f7SAndroid Build Coastguard Worker Variable *Var = Vars[VarNum];
286*03ce13f7SAndroid Build Coastguard Worker Str << "LR use before def, instruction " << LREnd[VarNum]
287*03ce13f7SAndroid Build Coastguard Worker << ", variable " << Var->getName() << "\n";
288*03ce13f7SAndroid Build Coastguard Worker }
289*03ce13f7SAndroid Build Coastguard Worker }
290*03ce13f7SAndroid Build Coastguard Worker llvm::report_fatal_error("initForInfOnly: Liveness error");
291*03ce13f7SAndroid Build Coastguard Worker }
292*03ce13f7SAndroid Build Coastguard Worker // This isn't actually a fatal condition, but it would be nice to know if we
293*03ce13f7SAndroid Build Coastguard Worker // somehow pre-calculated Unhandled's size wrong.
294*03ce13f7SAndroid Build Coastguard Worker assert(NumVars == 0);
295*03ce13f7SAndroid Build Coastguard Worker
296*03ce13f7SAndroid Build Coastguard Worker // Don't build up the list of Kills because we know that no infinite-weight
297*03ce13f7SAndroid Build Coastguard Worker // Variable has a live range spanning a call.
298*03ce13f7SAndroid Build Coastguard Worker Kills.clear();
299*03ce13f7SAndroid Build Coastguard Worker }
300*03ce13f7SAndroid Build Coastguard Worker
initForSecondChance()301*03ce13f7SAndroid Build Coastguard Worker void LinearScan::initForSecondChance() {
302*03ce13f7SAndroid Build Coastguard Worker TimerMarker T(TimerStack::TT_initUnhandled, Func);
303*03ce13f7SAndroid Build Coastguard Worker FindPreference = true;
304*03ce13f7SAndroid Build Coastguard Worker FindOverlap = true;
305*03ce13f7SAndroid Build Coastguard Worker const VarList &Vars = Func->getVariables();
306*03ce13f7SAndroid Build Coastguard Worker Unhandled.reserve(Vars.size());
307*03ce13f7SAndroid Build Coastguard Worker UnhandledPrecolored.reserve(Vars.size());
308*03ce13f7SAndroid Build Coastguard Worker for (Variable *Var : Vars) {
309*03ce13f7SAndroid Build Coastguard Worker if (Var->isRematerializable())
310*03ce13f7SAndroid Build Coastguard Worker continue;
311*03ce13f7SAndroid Build Coastguard Worker if (Var->hasReg()) {
312*03ce13f7SAndroid Build Coastguard Worker Var->untrimLiveRange();
313*03ce13f7SAndroid Build Coastguard Worker Var->setRegNumTmp(Var->getRegNum());
314*03ce13f7SAndroid Build Coastguard Worker Var->setMustHaveReg();
315*03ce13f7SAndroid Build Coastguard Worker UnhandledPrecolored.push_back(Var);
316*03ce13f7SAndroid Build Coastguard Worker Unhandled.push_back(Var);
317*03ce13f7SAndroid Build Coastguard Worker }
318*03ce13f7SAndroid Build Coastguard Worker }
319*03ce13f7SAndroid Build Coastguard Worker for (Variable *Var : Evicted) {
320*03ce13f7SAndroid Build Coastguard Worker Var->untrimLiveRange();
321*03ce13f7SAndroid Build Coastguard Worker Unhandled.push_back(Var);
322*03ce13f7SAndroid Build Coastguard Worker }
323*03ce13f7SAndroid Build Coastguard Worker }
324*03ce13f7SAndroid Build Coastguard Worker
init(RegAllocKind Kind,CfgSet<Variable * > ExcludeVars)325*03ce13f7SAndroid Build Coastguard Worker void LinearScan::init(RegAllocKind Kind, CfgSet<Variable *> ExcludeVars) {
326*03ce13f7SAndroid Build Coastguard Worker this->Kind = Kind;
327*03ce13f7SAndroid Build Coastguard Worker Unhandled.clear();
328*03ce13f7SAndroid Build Coastguard Worker UnhandledPrecolored.clear();
329*03ce13f7SAndroid Build Coastguard Worker Handled.clear();
330*03ce13f7SAndroid Build Coastguard Worker Inactive.clear();
331*03ce13f7SAndroid Build Coastguard Worker Active.clear();
332*03ce13f7SAndroid Build Coastguard Worker Vars.clear();
333*03ce13f7SAndroid Build Coastguard Worker Vars.reserve(Func->getVariables().size() - ExcludeVars.size());
334*03ce13f7SAndroid Build Coastguard Worker for (auto *Var : Func->getVariables()) {
335*03ce13f7SAndroid Build Coastguard Worker if (ExcludeVars.find(Var) == ExcludeVars.end())
336*03ce13f7SAndroid Build Coastguard Worker Vars.emplace_back(Var);
337*03ce13f7SAndroid Build Coastguard Worker }
338*03ce13f7SAndroid Build Coastguard Worker
339*03ce13f7SAndroid Build Coastguard Worker SizeT NumRegs = Target->getNumRegisters();
340*03ce13f7SAndroid Build Coastguard Worker RegAliases.resize(NumRegs);
341*03ce13f7SAndroid Build Coastguard Worker for (SizeT Reg = 0; Reg < NumRegs; ++Reg) {
342*03ce13f7SAndroid Build Coastguard Worker RegAliases[Reg] = &Target->getAliasesForRegister(RegNumT::fromInt(Reg));
343*03ce13f7SAndroid Build Coastguard Worker }
344*03ce13f7SAndroid Build Coastguard Worker
345*03ce13f7SAndroid Build Coastguard Worker switch (Kind) {
346*03ce13f7SAndroid Build Coastguard Worker case RAK_Unknown:
347*03ce13f7SAndroid Build Coastguard Worker llvm::report_fatal_error("Invalid RAK_Unknown");
348*03ce13f7SAndroid Build Coastguard Worker break;
349*03ce13f7SAndroid Build Coastguard Worker case RAK_Global:
350*03ce13f7SAndroid Build Coastguard Worker case RAK_Phi:
351*03ce13f7SAndroid Build Coastguard Worker initForGlobal();
352*03ce13f7SAndroid Build Coastguard Worker break;
353*03ce13f7SAndroid Build Coastguard Worker case RAK_InfOnly:
354*03ce13f7SAndroid Build Coastguard Worker initForInfOnly();
355*03ce13f7SAndroid Build Coastguard Worker break;
356*03ce13f7SAndroid Build Coastguard Worker case RAK_SecondChance:
357*03ce13f7SAndroid Build Coastguard Worker initForSecondChance();
358*03ce13f7SAndroid Build Coastguard Worker break;
359*03ce13f7SAndroid Build Coastguard Worker }
360*03ce13f7SAndroid Build Coastguard Worker
361*03ce13f7SAndroid Build Coastguard Worker Evicted.clear();
362*03ce13f7SAndroid Build Coastguard Worker
363*03ce13f7SAndroid Build Coastguard Worker auto CompareRanges = [](const Variable *L, const Variable *R) {
364*03ce13f7SAndroid Build Coastguard Worker InstNumberT Lstart = L->getLiveRange().getStart();
365*03ce13f7SAndroid Build Coastguard Worker InstNumberT Rstart = R->getLiveRange().getStart();
366*03ce13f7SAndroid Build Coastguard Worker if (Lstart == Rstart)
367*03ce13f7SAndroid Build Coastguard Worker return L->getIndex() < R->getIndex();
368*03ce13f7SAndroid Build Coastguard Worker return Lstart < Rstart;
369*03ce13f7SAndroid Build Coastguard Worker };
370*03ce13f7SAndroid Build Coastguard Worker // Do a reverse sort so that erasing elements (from the end) is fast.
371*03ce13f7SAndroid Build Coastguard Worker std::sort(Unhandled.rbegin(), Unhandled.rend(), CompareRanges);
372*03ce13f7SAndroid Build Coastguard Worker std::sort(UnhandledPrecolored.rbegin(), UnhandledPrecolored.rend(),
373*03ce13f7SAndroid Build Coastguard Worker CompareRanges);
374*03ce13f7SAndroid Build Coastguard Worker
375*03ce13f7SAndroid Build Coastguard Worker Handled.reserve(Unhandled.size());
376*03ce13f7SAndroid Build Coastguard Worker Inactive.reserve(Unhandled.size());
377*03ce13f7SAndroid Build Coastguard Worker Active.reserve(Unhandled.size());
378*03ce13f7SAndroid Build Coastguard Worker Evicted.reserve(Unhandled.size());
379*03ce13f7SAndroid Build Coastguard Worker }
380*03ce13f7SAndroid Build Coastguard Worker
381*03ce13f7SAndroid Build Coastguard Worker // This is called when Cur must be allocated a register but no registers are
382*03ce13f7SAndroid Build Coastguard Worker // available across Cur's live range. To handle this, we find a register that is
383*03ce13f7SAndroid Build Coastguard Worker // not explicitly used during Cur's live range, spill that register to a stack
384*03ce13f7SAndroid Build Coastguard Worker // location right before Cur's live range begins, and fill (reload) the register
385*03ce13f7SAndroid Build Coastguard Worker // from the stack location right after Cur's live range ends.
addSpillFill(IterationState & Iter)386*03ce13f7SAndroid Build Coastguard Worker void LinearScan::addSpillFill(IterationState &Iter) {
387*03ce13f7SAndroid Build Coastguard Worker // Identify the actual instructions that begin and end Iter.Cur's live range.
388*03ce13f7SAndroid Build Coastguard Worker // Iterate through Iter.Cur's node's instruction list until we find the actual
389*03ce13f7SAndroid Build Coastguard Worker // instructions with instruction numbers corresponding to Iter.Cur's recorded
390*03ce13f7SAndroid Build Coastguard Worker // live range endpoints. This sounds inefficient but shouldn't be a problem
391*03ce13f7SAndroid Build Coastguard Worker // in practice because:
392*03ce13f7SAndroid Build Coastguard Worker // (1) This function is almost never called in practice.
393*03ce13f7SAndroid Build Coastguard Worker // (2) Since this register over-subscription problem happens only for
394*03ce13f7SAndroid Build Coastguard Worker // phi-lowered instructions, the number of instructions in the node is
395*03ce13f7SAndroid Build Coastguard Worker // proportional to the number of phi instructions in the original node,
396*03ce13f7SAndroid Build Coastguard Worker // which is never very large in practice.
397*03ce13f7SAndroid Build Coastguard Worker // (3) We still have to iterate through all instructions of Iter.Cur's live
398*03ce13f7SAndroid Build Coastguard Worker // range to find all explicitly used registers (though the live range is
399*03ce13f7SAndroid Build Coastguard Worker // usually only 2-3 instructions), so the main cost that could be avoided
400*03ce13f7SAndroid Build Coastguard Worker // would be finding the instruction that begin's Iter.Cur's live range.
401*03ce13f7SAndroid Build Coastguard Worker assert(!Iter.Cur->getLiveRange().isEmpty());
402*03ce13f7SAndroid Build Coastguard Worker InstNumberT Start = Iter.Cur->getLiveRange().getStart();
403*03ce13f7SAndroid Build Coastguard Worker InstNumberT End = Iter.Cur->getLiveRange().getEnd();
404*03ce13f7SAndroid Build Coastguard Worker CfgNode *Node = Func->getVMetadata()->getLocalUseNode(Iter.Cur);
405*03ce13f7SAndroid Build Coastguard Worker assert(Node);
406*03ce13f7SAndroid Build Coastguard Worker InstList &Insts = Node->getInsts();
407*03ce13f7SAndroid Build Coastguard Worker InstList::iterator SpillPoint = Insts.end();
408*03ce13f7SAndroid Build Coastguard Worker InstList::iterator FillPoint = Insts.end();
409*03ce13f7SAndroid Build Coastguard Worker // Stop searching after we have found both the SpillPoint and the FillPoint.
410*03ce13f7SAndroid Build Coastguard Worker for (auto I = Insts.begin(), E = Insts.end();
411*03ce13f7SAndroid Build Coastguard Worker I != E && (SpillPoint == E || FillPoint == E); ++I) {
412*03ce13f7SAndroid Build Coastguard Worker if (I->getNumber() == Start)
413*03ce13f7SAndroid Build Coastguard Worker SpillPoint = I;
414*03ce13f7SAndroid Build Coastguard Worker if (I->getNumber() == End)
415*03ce13f7SAndroid Build Coastguard Worker FillPoint = I;
416*03ce13f7SAndroid Build Coastguard Worker if (SpillPoint != E) {
417*03ce13f7SAndroid Build Coastguard Worker // Remove from RegMask any physical registers referenced during Cur's live
418*03ce13f7SAndroid Build Coastguard Worker // range. Start looking after SpillPoint gets set, i.e. once Cur's live
419*03ce13f7SAndroid Build Coastguard Worker // range begins.
420*03ce13f7SAndroid Build Coastguard Worker FOREACH_VAR_IN_INST(Var, *I) {
421*03ce13f7SAndroid Build Coastguard Worker if (!Var->hasRegTmp())
422*03ce13f7SAndroid Build Coastguard Worker continue;
423*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[Var->getRegNumTmp()];
424*03ce13f7SAndroid Build Coastguard Worker for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
425*03ce13f7SAndroid Build Coastguard Worker Iter.RegMask[RegAlias] = false;
426*03ce13f7SAndroid Build Coastguard Worker }
427*03ce13f7SAndroid Build Coastguard Worker }
428*03ce13f7SAndroid Build Coastguard Worker }
429*03ce13f7SAndroid Build Coastguard Worker }
430*03ce13f7SAndroid Build Coastguard Worker assert(SpillPoint != Insts.end());
431*03ce13f7SAndroid Build Coastguard Worker assert(FillPoint != Insts.end());
432*03ce13f7SAndroid Build Coastguard Worker ++FillPoint;
433*03ce13f7SAndroid Build Coastguard Worker // TODO(stichnot): Randomize instead of *.begin() which maps to find_first().
434*03ce13f7SAndroid Build Coastguard Worker const RegNumT RegNum = *RegNumBVIter(Iter.RegMask).begin();
435*03ce13f7SAndroid Build Coastguard Worker Iter.Cur->setRegNumTmp(RegNum);
436*03ce13f7SAndroid Build Coastguard Worker Variable *Preg = Target->getPhysicalRegister(RegNum, Iter.Cur->getType());
437*03ce13f7SAndroid Build Coastguard Worker // TODO(stichnot): Add SpillLoc to VariablesMetadata tracking so that SpillLoc
438*03ce13f7SAndroid Build Coastguard Worker // is correctly identified as !isMultiBlock(), reducing stack frame size.
439*03ce13f7SAndroid Build Coastguard Worker Variable *SpillLoc = Func->makeVariable(Iter.Cur->getType());
440*03ce13f7SAndroid Build Coastguard Worker // Add "reg=FakeDef;spill=reg" before SpillPoint
441*03ce13f7SAndroid Build Coastguard Worker Target->lowerInst(Node, SpillPoint, InstFakeDef::create(Func, Preg));
442*03ce13f7SAndroid Build Coastguard Worker Target->lowerInst(Node, SpillPoint, InstAssign::create(Func, SpillLoc, Preg));
443*03ce13f7SAndroid Build Coastguard Worker // add "reg=spill;FakeUse(reg)" before FillPoint
444*03ce13f7SAndroid Build Coastguard Worker Target->lowerInst(Node, FillPoint, InstAssign::create(Func, Preg, SpillLoc));
445*03ce13f7SAndroid Build Coastguard Worker Target->lowerInst(Node, FillPoint, InstFakeUse::create(Func, Preg));
446*03ce13f7SAndroid Build Coastguard Worker }
447*03ce13f7SAndroid Build Coastguard Worker
handleActiveRangeExpiredOrInactive(const Variable * Cur)448*03ce13f7SAndroid Build Coastguard Worker void LinearScan::handleActiveRangeExpiredOrInactive(const Variable *Cur) {
449*03ce13f7SAndroid Build Coastguard Worker for (SizeT I = Active.size(); I > 0; --I) {
450*03ce13f7SAndroid Build Coastguard Worker const SizeT Index = I - 1;
451*03ce13f7SAndroid Build Coastguard Worker Variable *Item = Active[Index];
452*03ce13f7SAndroid Build Coastguard Worker Item->trimLiveRange(Cur->getLiveRange().getStart());
453*03ce13f7SAndroid Build Coastguard Worker bool Moved = false;
454*03ce13f7SAndroid Build Coastguard Worker if (Item->rangeEndsBefore(Cur)) {
455*03ce13f7SAndroid Build Coastguard Worker // Move Item from Active to Handled list.
456*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("Expiring ", Item);
457*03ce13f7SAndroid Build Coastguard Worker moveItem(Active, Index, Handled);
458*03ce13f7SAndroid Build Coastguard Worker Moved = true;
459*03ce13f7SAndroid Build Coastguard Worker } else if (!Item->rangeOverlapsStart(Cur)) {
460*03ce13f7SAndroid Build Coastguard Worker // Move Item from Active to Inactive list.
461*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("Inactivating ", Item);
462*03ce13f7SAndroid Build Coastguard Worker moveItem(Active, Index, Inactive);
463*03ce13f7SAndroid Build Coastguard Worker Moved = true;
464*03ce13f7SAndroid Build Coastguard Worker }
465*03ce13f7SAndroid Build Coastguard Worker if (Moved) {
466*03ce13f7SAndroid Build Coastguard Worker // Decrement Item from RegUses[].
467*03ce13f7SAndroid Build Coastguard Worker assert(Item->hasRegTmp());
468*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[Item->getRegNumTmp()];
469*03ce13f7SAndroid Build Coastguard Worker for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
470*03ce13f7SAndroid Build Coastguard Worker --RegUses[RegAlias];
471*03ce13f7SAndroid Build Coastguard Worker assert(RegUses[RegAlias] >= 0);
472*03ce13f7SAndroid Build Coastguard Worker }
473*03ce13f7SAndroid Build Coastguard Worker }
474*03ce13f7SAndroid Build Coastguard Worker }
475*03ce13f7SAndroid Build Coastguard Worker }
476*03ce13f7SAndroid Build Coastguard Worker
handleInactiveRangeExpiredOrReactivated(const Variable * Cur)477*03ce13f7SAndroid Build Coastguard Worker void LinearScan::handleInactiveRangeExpiredOrReactivated(const Variable *Cur) {
478*03ce13f7SAndroid Build Coastguard Worker for (SizeT I = Inactive.size(); I > 0; --I) {
479*03ce13f7SAndroid Build Coastguard Worker const SizeT Index = I - 1;
480*03ce13f7SAndroid Build Coastguard Worker Variable *Item = Inactive[Index];
481*03ce13f7SAndroid Build Coastguard Worker Item->trimLiveRange(Cur->getLiveRange().getStart());
482*03ce13f7SAndroid Build Coastguard Worker if (Item->rangeEndsBefore(Cur)) {
483*03ce13f7SAndroid Build Coastguard Worker // Move Item from Inactive to Handled list.
484*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("Expiring ", Item);
485*03ce13f7SAndroid Build Coastguard Worker moveItem(Inactive, Index, Handled);
486*03ce13f7SAndroid Build Coastguard Worker } else if (Item->rangeOverlapsStart(Cur)) {
487*03ce13f7SAndroid Build Coastguard Worker // Move Item from Inactive to Active list.
488*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("Reactivating ", Item);
489*03ce13f7SAndroid Build Coastguard Worker moveItem(Inactive, Index, Active);
490*03ce13f7SAndroid Build Coastguard Worker // Increment Item in RegUses[].
491*03ce13f7SAndroid Build Coastguard Worker assert(Item->hasRegTmp());
492*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[Item->getRegNumTmp()];
493*03ce13f7SAndroid Build Coastguard Worker for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
494*03ce13f7SAndroid Build Coastguard Worker assert(RegUses[RegAlias] >= 0);
495*03ce13f7SAndroid Build Coastguard Worker ++RegUses[RegAlias];
496*03ce13f7SAndroid Build Coastguard Worker }
497*03ce13f7SAndroid Build Coastguard Worker }
498*03ce13f7SAndroid Build Coastguard Worker }
499*03ce13f7SAndroid Build Coastguard Worker }
500*03ce13f7SAndroid Build Coastguard Worker
501*03ce13f7SAndroid Build Coastguard Worker // Infer register preference and allowable overlap. Only form a preference when
502*03ce13f7SAndroid Build Coastguard Worker // the current Variable has an unambiguous "first" definition. The preference is
503*03ce13f7SAndroid Build Coastguard Worker // some source Variable of the defining instruction that either is assigned a
504*03ce13f7SAndroid Build Coastguard Worker // register that is currently free, or that is assigned a register that is not
505*03ce13f7SAndroid Build Coastguard Worker // free but overlap is allowed. Overlap is allowed when the Variable under
506*03ce13f7SAndroid Build Coastguard Worker // consideration is single-definition, and its definition is a simple assignment
507*03ce13f7SAndroid Build Coastguard Worker // - i.e., the register gets copied/aliased but is never modified. Furthermore,
508*03ce13f7SAndroid Build Coastguard Worker // overlap is only allowed when preferred Variable definition instructions do
509*03ce13f7SAndroid Build Coastguard Worker // not appear within the current Variable's live range.
findRegisterPreference(IterationState & Iter)510*03ce13f7SAndroid Build Coastguard Worker void LinearScan::findRegisterPreference(IterationState &Iter) {
511*03ce13f7SAndroid Build Coastguard Worker Iter.Prefer = nullptr;
512*03ce13f7SAndroid Build Coastguard Worker Iter.PreferReg = RegNumT();
513*03ce13f7SAndroid Build Coastguard Worker Iter.AllowOverlap = false;
514*03ce13f7SAndroid Build Coastguard Worker
515*03ce13f7SAndroid Build Coastguard Worker if (!FindPreference)
516*03ce13f7SAndroid Build Coastguard Worker return;
517*03ce13f7SAndroid Build Coastguard Worker
518*03ce13f7SAndroid Build Coastguard Worker VariablesMetadata *VMetadata = Func->getVMetadata();
519*03ce13f7SAndroid Build Coastguard Worker const Inst *DefInst = VMetadata->getFirstDefinitionSingleBlock(Iter.Cur);
520*03ce13f7SAndroid Build Coastguard Worker if (DefInst == nullptr)
521*03ce13f7SAndroid Build Coastguard Worker return;
522*03ce13f7SAndroid Build Coastguard Worker
523*03ce13f7SAndroid Build Coastguard Worker assert(DefInst->getDest() == Iter.Cur);
524*03ce13f7SAndroid Build Coastguard Worker const bool IsSingleDefAssign =
525*03ce13f7SAndroid Build Coastguard Worker DefInst->isVarAssign() && !VMetadata->isMultiDef(Iter.Cur);
526*03ce13f7SAndroid Build Coastguard Worker FOREACH_VAR_IN_INST(SrcVar, *DefInst) {
527*03ce13f7SAndroid Build Coastguard Worker // Only consider source variables that have (so far) been assigned a
528*03ce13f7SAndroid Build Coastguard Worker // register.
529*03ce13f7SAndroid Build Coastguard Worker if (!SrcVar->hasRegTmp())
530*03ce13f7SAndroid Build Coastguard Worker continue;
531*03ce13f7SAndroid Build Coastguard Worker
532*03ce13f7SAndroid Build Coastguard Worker // That register must be one in the RegMask set, e.g. don't try to prefer
533*03ce13f7SAndroid Build Coastguard Worker // the stack pointer as a result of the stacksave intrinsic.
534*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[SrcVar->getRegNumTmp()];
535*03ce13f7SAndroid Build Coastguard Worker const int SrcReg = (Iter.RegMask & Aliases).find_first();
536*03ce13f7SAndroid Build Coastguard Worker if (SrcReg == -1)
537*03ce13f7SAndroid Build Coastguard Worker continue;
538*03ce13f7SAndroid Build Coastguard Worker
539*03ce13f7SAndroid Build Coastguard Worker if (FindOverlap && IsSingleDefAssign && !Iter.Free[SrcReg]) {
540*03ce13f7SAndroid Build Coastguard Worker // Don't bother trying to enable AllowOverlap if the register is already
541*03ce13f7SAndroid Build Coastguard Worker // free (hence the test on Iter.Free[SrcReg]).
542*03ce13f7SAndroid Build Coastguard Worker Iter.AllowOverlap = !overlapsDefs(Func, Iter.Cur, SrcVar);
543*03ce13f7SAndroid Build Coastguard Worker }
544*03ce13f7SAndroid Build Coastguard Worker if (Iter.AllowOverlap || Iter.Free[SrcReg]) {
545*03ce13f7SAndroid Build Coastguard Worker Iter.Prefer = SrcVar;
546*03ce13f7SAndroid Build Coastguard Worker Iter.PreferReg = RegNumT::fromInt(SrcReg);
547*03ce13f7SAndroid Build Coastguard Worker // Stop looking for a preference after the first valid preference is
548*03ce13f7SAndroid Build Coastguard Worker // found. One might think that we should look at all instruction
549*03ce13f7SAndroid Build Coastguard Worker // variables to find the best <Prefer,AllowOverlap> combination, but note
550*03ce13f7SAndroid Build Coastguard Worker // that AllowOverlap can only be true for a simple assignment statement
551*03ce13f7SAndroid Build Coastguard Worker // which can have only one source operand, so it's not possible for
552*03ce13f7SAndroid Build Coastguard Worker // AllowOverlap to be true beyond the first source operand.
553*03ce13f7SAndroid Build Coastguard Worker FOREACH_VAR_IN_INST_BREAK;
554*03ce13f7SAndroid Build Coastguard Worker }
555*03ce13f7SAndroid Build Coastguard Worker }
556*03ce13f7SAndroid Build Coastguard Worker if (BuildDefs::dump() && Verbose && Iter.Prefer) {
557*03ce13f7SAndroid Build Coastguard Worker Ostream &Str = Ctx->getStrDump();
558*03ce13f7SAndroid Build Coastguard Worker Str << "Initial Iter.Prefer=";
559*03ce13f7SAndroid Build Coastguard Worker Iter.Prefer->dump(Func);
560*03ce13f7SAndroid Build Coastguard Worker Str << " R=" << Iter.PreferReg << " LIVE=" << Iter.Prefer->getLiveRange()
561*03ce13f7SAndroid Build Coastguard Worker << " Overlap=" << Iter.AllowOverlap << "\n";
562*03ce13f7SAndroid Build Coastguard Worker }
563*03ce13f7SAndroid Build Coastguard Worker }
564*03ce13f7SAndroid Build Coastguard Worker
565*03ce13f7SAndroid Build Coastguard Worker // Remove registers from the Iter.Free[] list where an Inactive range overlaps
566*03ce13f7SAndroid Build Coastguard Worker // with the current range.
filterFreeWithInactiveRanges(IterationState & Iter)567*03ce13f7SAndroid Build Coastguard Worker void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) {
568*03ce13f7SAndroid Build Coastguard Worker for (const Variable *Item : Inactive) {
569*03ce13f7SAndroid Build Coastguard Worker if (!Item->rangeOverlaps(Iter.Cur))
570*03ce13f7SAndroid Build Coastguard Worker continue;
571*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[Item->getRegNumTmp()];
572*03ce13f7SAndroid Build Coastguard Worker for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
573*03ce13f7SAndroid Build Coastguard Worker // Don't assert(Iter.Free[RegAlias]) because in theory (though probably
574*03ce13f7SAndroid Build Coastguard Worker // never in practice) there could be two inactive variables that were
575*03ce13f7SAndroid Build Coastguard Worker // marked with AllowOverlap.
576*03ce13f7SAndroid Build Coastguard Worker Iter.Free[RegAlias] = false;
577*03ce13f7SAndroid Build Coastguard Worker Iter.FreeUnfiltered[RegAlias] = false;
578*03ce13f7SAndroid Build Coastguard Worker // Disable AllowOverlap if an Inactive variable, which is not Prefer,
579*03ce13f7SAndroid Build Coastguard Worker // shares Prefer's register, and has a definition within Cur's live range.
580*03ce13f7SAndroid Build Coastguard Worker if (Iter.AllowOverlap && Item != Iter.Prefer &&
581*03ce13f7SAndroid Build Coastguard Worker RegAlias == Iter.PreferReg && overlapsDefs(Func, Iter.Cur, Item)) {
582*03ce13f7SAndroid Build Coastguard Worker Iter.AllowOverlap = false;
583*03ce13f7SAndroid Build Coastguard Worker dumpDisableOverlap(Func, Item, "Inactive");
584*03ce13f7SAndroid Build Coastguard Worker }
585*03ce13f7SAndroid Build Coastguard Worker }
586*03ce13f7SAndroid Build Coastguard Worker }
587*03ce13f7SAndroid Build Coastguard Worker }
588*03ce13f7SAndroid Build Coastguard Worker
589*03ce13f7SAndroid Build Coastguard Worker // Remove registers from the Iter.Free[] list where an Unhandled pre-colored
590*03ce13f7SAndroid Build Coastguard Worker // range overlaps with the current range, and set those registers to infinite
591*03ce13f7SAndroid Build Coastguard Worker // weight so that they aren't candidates for eviction.
592*03ce13f7SAndroid Build Coastguard Worker // Cur->rangeEndsBefore(Item) is an early exit check that turns a guaranteed
593*03ce13f7SAndroid Build Coastguard Worker // O(N^2) algorithm into expected linear complexity.
filterFreeWithPrecoloredRanges(IterationState & Iter)594*03ce13f7SAndroid Build Coastguard Worker void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) {
595*03ce13f7SAndroid Build Coastguard Worker // TODO(stichnot): Partition UnhandledPrecolored according to register class,
596*03ce13f7SAndroid Build Coastguard Worker // to restrict the number of overlap comparisons needed.
597*03ce13f7SAndroid Build Coastguard Worker for (Variable *Item : reverse_range(UnhandledPrecolored)) {
598*03ce13f7SAndroid Build Coastguard Worker assert(Item->hasReg());
599*03ce13f7SAndroid Build Coastguard Worker if (Iter.Cur->rangeEndsBefore(Item))
600*03ce13f7SAndroid Build Coastguard Worker break;
601*03ce13f7SAndroid Build Coastguard Worker if (!Item->rangeOverlaps(Iter.Cur))
602*03ce13f7SAndroid Build Coastguard Worker continue;
603*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases =
604*03ce13f7SAndroid Build Coastguard Worker *RegAliases[Item->getRegNum()]; // Note: not getRegNumTmp()
605*03ce13f7SAndroid Build Coastguard Worker for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
606*03ce13f7SAndroid Build Coastguard Worker Iter.Weights[RegAlias].setWeight(RegWeight::Inf);
607*03ce13f7SAndroid Build Coastguard Worker Iter.Free[RegAlias] = false;
608*03ce13f7SAndroid Build Coastguard Worker Iter.FreeUnfiltered[RegAlias] = false;
609*03ce13f7SAndroid Build Coastguard Worker Iter.PrecoloredUnhandledMask[RegAlias] = true;
610*03ce13f7SAndroid Build Coastguard Worker // Disable Iter.AllowOverlap if the preferred register is one of these
611*03ce13f7SAndroid Build Coastguard Worker // pre-colored unhandled overlapping ranges.
612*03ce13f7SAndroid Build Coastguard Worker if (Iter.AllowOverlap && RegAlias == Iter.PreferReg) {
613*03ce13f7SAndroid Build Coastguard Worker Iter.AllowOverlap = false;
614*03ce13f7SAndroid Build Coastguard Worker dumpDisableOverlap(Func, Item, "PrecoloredUnhandled");
615*03ce13f7SAndroid Build Coastguard Worker }
616*03ce13f7SAndroid Build Coastguard Worker }
617*03ce13f7SAndroid Build Coastguard Worker }
618*03ce13f7SAndroid Build Coastguard Worker }
619*03ce13f7SAndroid Build Coastguard Worker
allocatePrecoloredRegister(Variable * Cur)620*03ce13f7SAndroid Build Coastguard Worker void LinearScan::allocatePrecoloredRegister(Variable *Cur) {
621*03ce13f7SAndroid Build Coastguard Worker const auto RegNum = Cur->getRegNum();
622*03ce13f7SAndroid Build Coastguard Worker // RegNumTmp should have already been set above.
623*03ce13f7SAndroid Build Coastguard Worker assert(Cur->getRegNumTmp() == RegNum);
624*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("Precoloring ", Cur);
625*03ce13f7SAndroid Build Coastguard Worker Active.push_back(Cur);
626*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[RegNum];
627*03ce13f7SAndroid Build Coastguard Worker for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
628*03ce13f7SAndroid Build Coastguard Worker assert(RegUses[RegAlias] >= 0);
629*03ce13f7SAndroid Build Coastguard Worker ++RegUses[RegAlias];
630*03ce13f7SAndroid Build Coastguard Worker }
631*03ce13f7SAndroid Build Coastguard Worker assert(!UnhandledPrecolored.empty());
632*03ce13f7SAndroid Build Coastguard Worker assert(UnhandledPrecolored.back() == Cur);
633*03ce13f7SAndroid Build Coastguard Worker UnhandledPrecolored.pop_back();
634*03ce13f7SAndroid Build Coastguard Worker }
635*03ce13f7SAndroid Build Coastguard Worker
allocatePreferredRegister(IterationState & Iter)636*03ce13f7SAndroid Build Coastguard Worker void LinearScan::allocatePreferredRegister(IterationState &Iter) {
637*03ce13f7SAndroid Build Coastguard Worker Iter.Cur->setRegNumTmp(Iter.PreferReg);
638*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("Preferring ", Iter.Cur);
639*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[Iter.PreferReg];
640*03ce13f7SAndroid Build Coastguard Worker for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
641*03ce13f7SAndroid Build Coastguard Worker assert(RegUses[RegAlias] >= 0);
642*03ce13f7SAndroid Build Coastguard Worker ++RegUses[RegAlias];
643*03ce13f7SAndroid Build Coastguard Worker }
644*03ce13f7SAndroid Build Coastguard Worker Active.push_back(Iter.Cur);
645*03ce13f7SAndroid Build Coastguard Worker }
646*03ce13f7SAndroid Build Coastguard Worker
allocateFreeRegister(IterationState & Iter,bool Filtered)647*03ce13f7SAndroid Build Coastguard Worker void LinearScan::allocateFreeRegister(IterationState &Iter, bool Filtered) {
648*03ce13f7SAndroid Build Coastguard Worker const RegNumT RegNum =
649*03ce13f7SAndroid Build Coastguard Worker *RegNumBVIter(Filtered ? Iter.Free : Iter.FreeUnfiltered).begin();
650*03ce13f7SAndroid Build Coastguard Worker Iter.Cur->setRegNumTmp(RegNum);
651*03ce13f7SAndroid Build Coastguard Worker if (Filtered)
652*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("Allocating Y ", Iter.Cur);
653*03ce13f7SAndroid Build Coastguard Worker else
654*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("Allocating X ", Iter.Cur);
655*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[RegNum];
656*03ce13f7SAndroid Build Coastguard Worker for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
657*03ce13f7SAndroid Build Coastguard Worker assert(RegUses[RegAlias] >= 0);
658*03ce13f7SAndroid Build Coastguard Worker ++RegUses[RegAlias];
659*03ce13f7SAndroid Build Coastguard Worker }
660*03ce13f7SAndroid Build Coastguard Worker Active.push_back(Iter.Cur);
661*03ce13f7SAndroid Build Coastguard Worker }
662*03ce13f7SAndroid Build Coastguard Worker
handleNoFreeRegisters(IterationState & Iter)663*03ce13f7SAndroid Build Coastguard Worker void LinearScan::handleNoFreeRegisters(IterationState &Iter) {
664*03ce13f7SAndroid Build Coastguard Worker // Check Active ranges.
665*03ce13f7SAndroid Build Coastguard Worker for (const Variable *Item : Active) {
666*03ce13f7SAndroid Build Coastguard Worker assert(Item->rangeOverlaps(Iter.Cur));
667*03ce13f7SAndroid Build Coastguard Worker assert(Item->hasRegTmp());
668*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[Item->getRegNumTmp()];
669*03ce13f7SAndroid Build Coastguard Worker // We add the Item's weight to each alias/subregister to represent that,
670*03ce13f7SAndroid Build Coastguard Worker // should we decide to pick any of them, then we would incur that many
671*03ce13f7SAndroid Build Coastguard Worker // memory accesses.
672*03ce13f7SAndroid Build Coastguard Worker RegWeight W = Item->getWeight(Func);
673*03ce13f7SAndroid Build Coastguard Worker for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
674*03ce13f7SAndroid Build Coastguard Worker Iter.Weights[RegAlias].addWeight(W);
675*03ce13f7SAndroid Build Coastguard Worker }
676*03ce13f7SAndroid Build Coastguard Worker }
677*03ce13f7SAndroid Build Coastguard Worker // Same as above, but check Inactive ranges instead of Active.
678*03ce13f7SAndroid Build Coastguard Worker for (const Variable *Item : Inactive) {
679*03ce13f7SAndroid Build Coastguard Worker if (!Item->rangeOverlaps(Iter.Cur))
680*03ce13f7SAndroid Build Coastguard Worker continue;
681*03ce13f7SAndroid Build Coastguard Worker assert(Item->hasRegTmp());
682*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[Item->getRegNumTmp()];
683*03ce13f7SAndroid Build Coastguard Worker RegWeight W = Item->getWeight(Func);
684*03ce13f7SAndroid Build Coastguard Worker for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
685*03ce13f7SAndroid Build Coastguard Worker Iter.Weights[RegAlias].addWeight(W);
686*03ce13f7SAndroid Build Coastguard Worker }
687*03ce13f7SAndroid Build Coastguard Worker }
688*03ce13f7SAndroid Build Coastguard Worker
689*03ce13f7SAndroid Build Coastguard Worker // All the weights are now calculated. Find the register with smallest weight.
690*03ce13f7SAndroid Build Coastguard Worker int32_t MinWeightIndex = findMinWeightIndex(Iter.RegMask, Iter.Weights);
691*03ce13f7SAndroid Build Coastguard Worker
692*03ce13f7SAndroid Build Coastguard Worker if (MinWeightIndex < 0 ||
693*03ce13f7SAndroid Build Coastguard Worker Iter.Cur->getWeight(Func) <= Iter.Weights[MinWeightIndex]) {
694*03ce13f7SAndroid Build Coastguard Worker if (!Iter.Cur->mustHaveReg()) {
695*03ce13f7SAndroid Build Coastguard Worker // Iter.Cur doesn't have priority over any other live ranges, so don't
696*03ce13f7SAndroid Build Coastguard Worker // allocate any register to it, and move it to the Handled state.
697*03ce13f7SAndroid Build Coastguard Worker Handled.push_back(Iter.Cur);
698*03ce13f7SAndroid Build Coastguard Worker return;
699*03ce13f7SAndroid Build Coastguard Worker }
700*03ce13f7SAndroid Build Coastguard Worker if (Kind == RAK_Phi) {
701*03ce13f7SAndroid Build Coastguard Worker // Iter.Cur is infinite-weight but all physical registers are already
702*03ce13f7SAndroid Build Coastguard Worker // taken, so we need to force one to be temporarily available.
703*03ce13f7SAndroid Build Coastguard Worker addSpillFill(Iter);
704*03ce13f7SAndroid Build Coastguard Worker Handled.push_back(Iter.Cur);
705*03ce13f7SAndroid Build Coastguard Worker return;
706*03ce13f7SAndroid Build Coastguard Worker }
707*03ce13f7SAndroid Build Coastguard Worker // The remaining portion of the enclosing "if" block should only be
708*03ce13f7SAndroid Build Coastguard Worker // reachable if we are manually limiting physical registers for testing.
709*03ce13f7SAndroid Build Coastguard Worker if (UseReserve) {
710*03ce13f7SAndroid Build Coastguard Worker if (Iter.FreeUnfiltered.any()) {
711*03ce13f7SAndroid Build Coastguard Worker // There is some available physical register held in reserve, so use it.
712*03ce13f7SAndroid Build Coastguard Worker constexpr bool NotFiltered = false;
713*03ce13f7SAndroid Build Coastguard Worker allocateFreeRegister(Iter, NotFiltered);
714*03ce13f7SAndroid Build Coastguard Worker // Iter.Cur is now on the Active list.
715*03ce13f7SAndroid Build Coastguard Worker return;
716*03ce13f7SAndroid Build Coastguard Worker }
717*03ce13f7SAndroid Build Coastguard Worker // At this point, we need to find some reserve register that is already
718*03ce13f7SAndroid Build Coastguard Worker // assigned to a non-infinite-weight variable. This could happen if some
719*03ce13f7SAndroid Build Coastguard Worker // variable was previously assigned an alias of such a register.
720*03ce13f7SAndroid Build Coastguard Worker MinWeightIndex = findMinWeightIndex(Iter.RegMaskUnfiltered, Iter.Weights);
721*03ce13f7SAndroid Build Coastguard Worker }
722*03ce13f7SAndroid Build Coastguard Worker if (Iter.Cur->getWeight(Func) <= Iter.Weights[MinWeightIndex]) {
723*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("Failing ", Iter.Cur);
724*03ce13f7SAndroid Build Coastguard Worker Func->setError("Unable to find a physical register for an "
725*03ce13f7SAndroid Build Coastguard Worker "infinite-weight live range "
726*03ce13f7SAndroid Build Coastguard Worker "(consider using -reg-reserve): " +
727*03ce13f7SAndroid Build Coastguard Worker Iter.Cur->getName());
728*03ce13f7SAndroid Build Coastguard Worker Handled.push_back(Iter.Cur);
729*03ce13f7SAndroid Build Coastguard Worker return;
730*03ce13f7SAndroid Build Coastguard Worker }
731*03ce13f7SAndroid Build Coastguard Worker // At this point, MinWeightIndex points to a valid reserve register to
732*03ce13f7SAndroid Build Coastguard Worker // reallocate to Iter.Cur, so drop into the eviction code.
733*03ce13f7SAndroid Build Coastguard Worker }
734*03ce13f7SAndroid Build Coastguard Worker
735*03ce13f7SAndroid Build Coastguard Worker // Evict all live ranges in Active that register number MinWeightIndex is
736*03ce13f7SAndroid Build Coastguard Worker // assigned to.
737*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[MinWeightIndex];
738*03ce13f7SAndroid Build Coastguard Worker for (SizeT I = Active.size(); I > 0; --I) {
739*03ce13f7SAndroid Build Coastguard Worker const SizeT Index = I - 1;
740*03ce13f7SAndroid Build Coastguard Worker Variable *Item = Active[Index];
741*03ce13f7SAndroid Build Coastguard Worker const auto RegNum = Item->getRegNumTmp();
742*03ce13f7SAndroid Build Coastguard Worker if (Aliases[RegNum]) {
743*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("Evicting A ", Item);
744*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[RegNum];
745*03ce13f7SAndroid Build Coastguard Worker for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
746*03ce13f7SAndroid Build Coastguard Worker --RegUses[RegAlias];
747*03ce13f7SAndroid Build Coastguard Worker assert(RegUses[RegAlias] >= 0);
748*03ce13f7SAndroid Build Coastguard Worker }
749*03ce13f7SAndroid Build Coastguard Worker Item->setRegNumTmp(RegNumT());
750*03ce13f7SAndroid Build Coastguard Worker moveItem(Active, Index, Handled);
751*03ce13f7SAndroid Build Coastguard Worker Evicted.push_back(Item);
752*03ce13f7SAndroid Build Coastguard Worker }
753*03ce13f7SAndroid Build Coastguard Worker }
754*03ce13f7SAndroid Build Coastguard Worker // Do the same for Inactive.
755*03ce13f7SAndroid Build Coastguard Worker for (SizeT I = Inactive.size(); I > 0; --I) {
756*03ce13f7SAndroid Build Coastguard Worker const SizeT Index = I - 1;
757*03ce13f7SAndroid Build Coastguard Worker Variable *Item = Inactive[Index];
758*03ce13f7SAndroid Build Coastguard Worker // Note: The Item->rangeOverlaps(Cur) clause is not part of the description
759*03ce13f7SAndroid Build Coastguard Worker // of AssignMemLoc() in the original paper. But there doesn't seem to be any
760*03ce13f7SAndroid Build Coastguard Worker // need to evict an inactive live range that doesn't overlap with the live
761*03ce13f7SAndroid Build Coastguard Worker // range currently being considered. It's especially bad if we would end up
762*03ce13f7SAndroid Build Coastguard Worker // evicting an infinite-weight but currently-inactive live range. The most
763*03ce13f7SAndroid Build Coastguard Worker // common situation for this would be a scratch register kill set for call
764*03ce13f7SAndroid Build Coastguard Worker // instructions.
765*03ce13f7SAndroid Build Coastguard Worker if (Aliases[Item->getRegNumTmp()] && Item->rangeOverlaps(Iter.Cur)) {
766*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("Evicting I ", Item);
767*03ce13f7SAndroid Build Coastguard Worker Item->setRegNumTmp(RegNumT());
768*03ce13f7SAndroid Build Coastguard Worker moveItem(Inactive, Index, Handled);
769*03ce13f7SAndroid Build Coastguard Worker Evicted.push_back(Item);
770*03ce13f7SAndroid Build Coastguard Worker }
771*03ce13f7SAndroid Build Coastguard Worker }
772*03ce13f7SAndroid Build Coastguard Worker // Assign the register to Cur.
773*03ce13f7SAndroid Build Coastguard Worker Iter.Cur->setRegNumTmp(RegNumT::fromInt(MinWeightIndex));
774*03ce13f7SAndroid Build Coastguard Worker for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
775*03ce13f7SAndroid Build Coastguard Worker assert(RegUses[RegAlias] >= 0);
776*03ce13f7SAndroid Build Coastguard Worker ++RegUses[RegAlias];
777*03ce13f7SAndroid Build Coastguard Worker }
778*03ce13f7SAndroid Build Coastguard Worker Active.push_back(Iter.Cur);
779*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("Allocating Z ", Iter.Cur);
780*03ce13f7SAndroid Build Coastguard Worker }
781*03ce13f7SAndroid Build Coastguard Worker
assignFinalRegisters(const SmallBitVector & RegMaskFull)782*03ce13f7SAndroid Build Coastguard Worker void LinearScan::assignFinalRegisters(const SmallBitVector &RegMaskFull) {
783*03ce13f7SAndroid Build Coastguard Worker // Finish up by setting RegNum = RegNumTmp (or a random permutation thereof)
784*03ce13f7SAndroid Build Coastguard Worker // for each Variable.
785*03ce13f7SAndroid Build Coastguard Worker for (Variable *Item : Handled) {
786*03ce13f7SAndroid Build Coastguard Worker const auto RegNum = Item->getRegNumTmp();
787*03ce13f7SAndroid Build Coastguard Worker auto AssignedRegNum = RegNum;
788*03ce13f7SAndroid Build Coastguard Worker
789*03ce13f7SAndroid Build Coastguard Worker if (BuildDefs::dump() && Verbose) {
790*03ce13f7SAndroid Build Coastguard Worker Ostream &Str = Ctx->getStrDump();
791*03ce13f7SAndroid Build Coastguard Worker if (!Item->hasRegTmp()) {
792*03ce13f7SAndroid Build Coastguard Worker Str << "Not assigning ";
793*03ce13f7SAndroid Build Coastguard Worker Item->dump(Func);
794*03ce13f7SAndroid Build Coastguard Worker Str << "\n";
795*03ce13f7SAndroid Build Coastguard Worker } else {
796*03ce13f7SAndroid Build Coastguard Worker Str << (AssignedRegNum == Item->getRegNum() ? "Reassigning "
797*03ce13f7SAndroid Build Coastguard Worker : "Assigning ")
798*03ce13f7SAndroid Build Coastguard Worker << Target->getRegName(AssignedRegNum, Item->getType()) << "(r"
799*03ce13f7SAndroid Build Coastguard Worker << AssignedRegNum << ") to ";
800*03ce13f7SAndroid Build Coastguard Worker Item->dump(Func);
801*03ce13f7SAndroid Build Coastguard Worker Str << "\n";
802*03ce13f7SAndroid Build Coastguard Worker }
803*03ce13f7SAndroid Build Coastguard Worker }
804*03ce13f7SAndroid Build Coastguard Worker Item->setRegNum(AssignedRegNum);
805*03ce13f7SAndroid Build Coastguard Worker }
806*03ce13f7SAndroid Build Coastguard Worker }
807*03ce13f7SAndroid Build Coastguard Worker
808*03ce13f7SAndroid Build Coastguard Worker // Implements the linear-scan algorithm. Based on "Linear Scan Register
809*03ce13f7SAndroid Build Coastguard Worker // Allocation in the Context of SSA Form and Register Constraints" by Hanspeter
810*03ce13f7SAndroid Build Coastguard Worker // Mössenböck and Michael Pfeiffer,
811*03ce13f7SAndroid Build Coastguard Worker // ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF. This implementation is
812*03ce13f7SAndroid Build Coastguard Worker // modified to take affinity into account and allow two interfering variables to
813*03ce13f7SAndroid Build Coastguard Worker // share the same register in certain cases.
814*03ce13f7SAndroid Build Coastguard Worker //
815*03ce13f7SAndroid Build Coastguard Worker // Requires running Cfg::liveness(Liveness_Intervals) in preparation. Results
816*03ce13f7SAndroid Build Coastguard Worker // are assigned to Variable::RegNum for each Variable.
scan(const SmallBitVector & RegMaskFull)817*03ce13f7SAndroid Build Coastguard Worker void LinearScan::scan(const SmallBitVector &RegMaskFull) {
818*03ce13f7SAndroid Build Coastguard Worker TimerMarker T(TimerStack::TT_linearScan, Func);
819*03ce13f7SAndroid Build Coastguard Worker assert(RegMaskFull.any()); // Sanity check
820*03ce13f7SAndroid Build Coastguard Worker if (Verbose)
821*03ce13f7SAndroid Build Coastguard Worker Ctx->lockStr();
822*03ce13f7SAndroid Build Coastguard Worker Func->resetCurrentNode();
823*03ce13f7SAndroid Build Coastguard Worker const size_t NumRegisters = RegMaskFull.size();
824*03ce13f7SAndroid Build Coastguard Worker
825*03ce13f7SAndroid Build Coastguard Worker // Build a LiveRange representing the Kills list.
826*03ce13f7SAndroid Build Coastguard Worker LiveRange KillsRange(Kills);
827*03ce13f7SAndroid Build Coastguard Worker KillsRange.untrim();
828*03ce13f7SAndroid Build Coastguard Worker
829*03ce13f7SAndroid Build Coastguard Worker // Reset the register use count.
830*03ce13f7SAndroid Build Coastguard Worker RegUses.resize(NumRegisters);
831*03ce13f7SAndroid Build Coastguard Worker std::fill(RegUses.begin(), RegUses.end(), 0);
832*03ce13f7SAndroid Build Coastguard Worker
833*03ce13f7SAndroid Build Coastguard Worker // Unhandled is already set to all ranges in increasing order of start points.
834*03ce13f7SAndroid Build Coastguard Worker assert(Active.empty());
835*03ce13f7SAndroid Build Coastguard Worker assert(Inactive.empty());
836*03ce13f7SAndroid Build Coastguard Worker assert(Handled.empty());
837*03ce13f7SAndroid Build Coastguard Worker const TargetLowering::RegSetMask RegsInclude =
838*03ce13f7SAndroid Build Coastguard Worker TargetLowering::RegSet_CallerSave;
839*03ce13f7SAndroid Build Coastguard Worker const TargetLowering::RegSetMask RegsExclude = TargetLowering::RegSet_None;
840*03ce13f7SAndroid Build Coastguard Worker const SmallBitVector KillsMask =
841*03ce13f7SAndroid Build Coastguard Worker Target->getRegisterSet(RegsInclude, RegsExclude);
842*03ce13f7SAndroid Build Coastguard Worker
843*03ce13f7SAndroid Build Coastguard Worker // Allocate memory once outside the loop.
844*03ce13f7SAndroid Build Coastguard Worker IterationState Iter;
845*03ce13f7SAndroid Build Coastguard Worker Iter.Weights.reserve(NumRegisters);
846*03ce13f7SAndroid Build Coastguard Worker Iter.PrecoloredUnhandledMask.reserve(NumRegisters);
847*03ce13f7SAndroid Build Coastguard Worker
848*03ce13f7SAndroid Build Coastguard Worker while (!Unhandled.empty()) {
849*03ce13f7SAndroid Build Coastguard Worker Iter.Cur = Unhandled.back();
850*03ce13f7SAndroid Build Coastguard Worker Unhandled.pop_back();
851*03ce13f7SAndroid Build Coastguard Worker dumpLiveRangeTrace("\nConsidering ", Iter.Cur);
852*03ce13f7SAndroid Build Coastguard Worker if (UseReserve)
853*03ce13f7SAndroid Build Coastguard Worker assert(Target->getAllRegistersForVariable(Iter.Cur).any());
854*03ce13f7SAndroid Build Coastguard Worker else
855*03ce13f7SAndroid Build Coastguard Worker assert(Target->getRegistersForVariable(Iter.Cur).any());
856*03ce13f7SAndroid Build Coastguard Worker Iter.RegMask = RegMaskFull & Target->getRegistersForVariable(Iter.Cur);
857*03ce13f7SAndroid Build Coastguard Worker Iter.RegMaskUnfiltered =
858*03ce13f7SAndroid Build Coastguard Worker RegMaskFull & Target->getAllRegistersForVariable(Iter.Cur);
859*03ce13f7SAndroid Build Coastguard Worker KillsRange.trim(Iter.Cur->getLiveRange().getStart());
860*03ce13f7SAndroid Build Coastguard Worker
861*03ce13f7SAndroid Build Coastguard Worker // Check for pre-colored ranges. If Cur is pre-colored, it definitely gets
862*03ce13f7SAndroid Build Coastguard Worker // that register. Previously processed live ranges would have avoided that
863*03ce13f7SAndroid Build Coastguard Worker // register due to it being pre-colored. Future processed live ranges won't
864*03ce13f7SAndroid Build Coastguard Worker // evict that register because the live range has infinite weight.
865*03ce13f7SAndroid Build Coastguard Worker if (Iter.Cur->hasReg()) {
866*03ce13f7SAndroid Build Coastguard Worker allocatePrecoloredRegister(Iter.Cur);
867*03ce13f7SAndroid Build Coastguard Worker continue;
868*03ce13f7SAndroid Build Coastguard Worker }
869*03ce13f7SAndroid Build Coastguard Worker
870*03ce13f7SAndroid Build Coastguard Worker handleActiveRangeExpiredOrInactive(Iter.Cur);
871*03ce13f7SAndroid Build Coastguard Worker handleInactiveRangeExpiredOrReactivated(Iter.Cur);
872*03ce13f7SAndroid Build Coastguard Worker
873*03ce13f7SAndroid Build Coastguard Worker // Calculate available registers into Iter.Free[] and Iter.FreeUnfiltered[].
874*03ce13f7SAndroid Build Coastguard Worker Iter.Free = Iter.RegMask;
875*03ce13f7SAndroid Build Coastguard Worker Iter.FreeUnfiltered = Iter.RegMaskUnfiltered;
876*03ce13f7SAndroid Build Coastguard Worker for (SizeT i = 0; i < Iter.RegMask.size(); ++i) {
877*03ce13f7SAndroid Build Coastguard Worker if (RegUses[i] > 0) {
878*03ce13f7SAndroid Build Coastguard Worker Iter.Free[i] = false;
879*03ce13f7SAndroid Build Coastguard Worker Iter.FreeUnfiltered[i] = false;
880*03ce13f7SAndroid Build Coastguard Worker }
881*03ce13f7SAndroid Build Coastguard Worker }
882*03ce13f7SAndroid Build Coastguard Worker
883*03ce13f7SAndroid Build Coastguard Worker findRegisterPreference(Iter);
884*03ce13f7SAndroid Build Coastguard Worker filterFreeWithInactiveRanges(Iter);
885*03ce13f7SAndroid Build Coastguard Worker
886*03ce13f7SAndroid Build Coastguard Worker // Disable AllowOverlap if an Active variable, which is not Prefer, shares
887*03ce13f7SAndroid Build Coastguard Worker // Prefer's register, and has a definition within Cur's live range.
888*03ce13f7SAndroid Build Coastguard Worker if (Iter.AllowOverlap) {
889*03ce13f7SAndroid Build Coastguard Worker const auto &Aliases = *RegAliases[Iter.PreferReg];
890*03ce13f7SAndroid Build Coastguard Worker for (const Variable *Item : Active) {
891*03ce13f7SAndroid Build Coastguard Worker const RegNumT RegNum = Item->getRegNumTmp();
892*03ce13f7SAndroid Build Coastguard Worker if (Item != Iter.Prefer && Aliases[RegNum] &&
893*03ce13f7SAndroid Build Coastguard Worker overlapsDefs(Func, Iter.Cur, Item)) {
894*03ce13f7SAndroid Build Coastguard Worker Iter.AllowOverlap = false;
895*03ce13f7SAndroid Build Coastguard Worker dumpDisableOverlap(Func, Item, "Active");
896*03ce13f7SAndroid Build Coastguard Worker }
897*03ce13f7SAndroid Build Coastguard Worker }
898*03ce13f7SAndroid Build Coastguard Worker }
899*03ce13f7SAndroid Build Coastguard Worker
900*03ce13f7SAndroid Build Coastguard Worker Iter.Weights.resize(Iter.RegMask.size());
901*03ce13f7SAndroid Build Coastguard Worker std::fill(Iter.Weights.begin(), Iter.Weights.end(), RegWeight());
902*03ce13f7SAndroid Build Coastguard Worker
903*03ce13f7SAndroid Build Coastguard Worker Iter.PrecoloredUnhandledMask.resize(Iter.RegMask.size());
904*03ce13f7SAndroid Build Coastguard Worker Iter.PrecoloredUnhandledMask.reset();
905*03ce13f7SAndroid Build Coastguard Worker
906*03ce13f7SAndroid Build Coastguard Worker filterFreeWithPrecoloredRanges(Iter);
907*03ce13f7SAndroid Build Coastguard Worker
908*03ce13f7SAndroid Build Coastguard Worker // Remove scratch registers from the Iter.Free[] list, and mark their
909*03ce13f7SAndroid Build Coastguard Worker // Iter.Weights[] as infinite, if KillsRange overlaps Cur's live range.
910*03ce13f7SAndroid Build Coastguard Worker constexpr bool UseTrimmed = true;
911*03ce13f7SAndroid Build Coastguard Worker if (Iter.Cur->getLiveRange().overlaps(KillsRange, UseTrimmed)) {
912*03ce13f7SAndroid Build Coastguard Worker Iter.Free.reset(KillsMask);
913*03ce13f7SAndroid Build Coastguard Worker Iter.FreeUnfiltered.reset(KillsMask);
914*03ce13f7SAndroid Build Coastguard Worker for (RegNumT i : RegNumBVIter(KillsMask)) {
915*03ce13f7SAndroid Build Coastguard Worker Iter.Weights[i].setWeight(RegWeight::Inf);
916*03ce13f7SAndroid Build Coastguard Worker if (Iter.PreferReg == i)
917*03ce13f7SAndroid Build Coastguard Worker Iter.AllowOverlap = false;
918*03ce13f7SAndroid Build Coastguard Worker }
919*03ce13f7SAndroid Build Coastguard Worker }
920*03ce13f7SAndroid Build Coastguard Worker
921*03ce13f7SAndroid Build Coastguard Worker // Print info about physical register availability.
922*03ce13f7SAndroid Build Coastguard Worker if (BuildDefs::dump() && Verbose) {
923*03ce13f7SAndroid Build Coastguard Worker Ostream &Str = Ctx->getStrDump();
924*03ce13f7SAndroid Build Coastguard Worker for (RegNumT i : RegNumBVIter(Iter.RegMaskUnfiltered)) {
925*03ce13f7SAndroid Build Coastguard Worker Str << Target->getRegName(i, Iter.Cur->getType()) << "(U=" << RegUses[i]
926*03ce13f7SAndroid Build Coastguard Worker << ",F=" << Iter.Free[i] << ",P=" << Iter.PrecoloredUnhandledMask[i]
927*03ce13f7SAndroid Build Coastguard Worker << ") ";
928*03ce13f7SAndroid Build Coastguard Worker }
929*03ce13f7SAndroid Build Coastguard Worker Str << "\n";
930*03ce13f7SAndroid Build Coastguard Worker }
931*03ce13f7SAndroid Build Coastguard Worker
932*03ce13f7SAndroid Build Coastguard Worker if (Iter.Prefer && (Iter.AllowOverlap || Iter.Free[Iter.PreferReg])) {
933*03ce13f7SAndroid Build Coastguard Worker // First choice: a preferred register that is either free or is allowed to
934*03ce13f7SAndroid Build Coastguard Worker // overlap with its linked variable.
935*03ce13f7SAndroid Build Coastguard Worker allocatePreferredRegister(Iter);
936*03ce13f7SAndroid Build Coastguard Worker } else if (Iter.Free.any()) {
937*03ce13f7SAndroid Build Coastguard Worker // Second choice: any free register.
938*03ce13f7SAndroid Build Coastguard Worker constexpr bool Filtered = true;
939*03ce13f7SAndroid Build Coastguard Worker allocateFreeRegister(Iter, Filtered);
940*03ce13f7SAndroid Build Coastguard Worker } else {
941*03ce13f7SAndroid Build Coastguard Worker // Fallback: there are no free registers, so we look for the lowest-weight
942*03ce13f7SAndroid Build Coastguard Worker // register and see if Cur has higher weight.
943*03ce13f7SAndroid Build Coastguard Worker handleNoFreeRegisters(Iter);
944*03ce13f7SAndroid Build Coastguard Worker }
945*03ce13f7SAndroid Build Coastguard Worker dump(Func);
946*03ce13f7SAndroid Build Coastguard Worker }
947*03ce13f7SAndroid Build Coastguard Worker
948*03ce13f7SAndroid Build Coastguard Worker // Move anything Active or Inactive to Handled for easier handling.
949*03ce13f7SAndroid Build Coastguard Worker Handled.insert(Handled.end(), Active.begin(), Active.end());
950*03ce13f7SAndroid Build Coastguard Worker Active.clear();
951*03ce13f7SAndroid Build Coastguard Worker Handled.insert(Handled.end(), Inactive.begin(), Inactive.end());
952*03ce13f7SAndroid Build Coastguard Worker Inactive.clear();
953*03ce13f7SAndroid Build Coastguard Worker dump(Func);
954*03ce13f7SAndroid Build Coastguard Worker
955*03ce13f7SAndroid Build Coastguard Worker assignFinalRegisters(RegMaskFull);
956*03ce13f7SAndroid Build Coastguard Worker
957*03ce13f7SAndroid Build Coastguard Worker if (Verbose)
958*03ce13f7SAndroid Build Coastguard Worker Ctx->unlockStr();
959*03ce13f7SAndroid Build Coastguard Worker }
960*03ce13f7SAndroid Build Coastguard Worker
961*03ce13f7SAndroid Build Coastguard Worker // ======================== Dump routines ======================== //
962*03ce13f7SAndroid Build Coastguard Worker
dumpLiveRangeTrace(const char * Label,const Variable * Item)963*03ce13f7SAndroid Build Coastguard Worker void LinearScan::dumpLiveRangeTrace(const char *Label, const Variable *Item) {
964*03ce13f7SAndroid Build Coastguard Worker if (!BuildDefs::dump())
965*03ce13f7SAndroid Build Coastguard Worker return;
966*03ce13f7SAndroid Build Coastguard Worker
967*03ce13f7SAndroid Build Coastguard Worker if (Verbose) {
968*03ce13f7SAndroid Build Coastguard Worker Ostream &Str = Ctx->getStrDump();
969*03ce13f7SAndroid Build Coastguard Worker Str << Label;
970*03ce13f7SAndroid Build Coastguard Worker dumpLiveRange(Item, Func);
971*03ce13f7SAndroid Build Coastguard Worker Str << "\n";
972*03ce13f7SAndroid Build Coastguard Worker }
973*03ce13f7SAndroid Build Coastguard Worker }
974*03ce13f7SAndroid Build Coastguard Worker
dump(Cfg * Func) const975*03ce13f7SAndroid Build Coastguard Worker void LinearScan::dump(Cfg *Func) const {
976*03ce13f7SAndroid Build Coastguard Worker if (!BuildDefs::dump())
977*03ce13f7SAndroid Build Coastguard Worker return;
978*03ce13f7SAndroid Build Coastguard Worker if (!Verbose)
979*03ce13f7SAndroid Build Coastguard Worker return;
980*03ce13f7SAndroid Build Coastguard Worker Ostream &Str = Func->getContext()->getStrDump();
981*03ce13f7SAndroid Build Coastguard Worker Func->resetCurrentNode();
982*03ce13f7SAndroid Build Coastguard Worker Str << "**** Current regalloc state:\n";
983*03ce13f7SAndroid Build Coastguard Worker Str << "++++++ Handled:\n";
984*03ce13f7SAndroid Build Coastguard Worker for (const Variable *Item : Handled) {
985*03ce13f7SAndroid Build Coastguard Worker dumpLiveRange(Item, Func);
986*03ce13f7SAndroid Build Coastguard Worker Str << "\n";
987*03ce13f7SAndroid Build Coastguard Worker }
988*03ce13f7SAndroid Build Coastguard Worker Str << "++++++ Unhandled:\n";
989*03ce13f7SAndroid Build Coastguard Worker for (const Variable *Item : reverse_range(Unhandled)) {
990*03ce13f7SAndroid Build Coastguard Worker dumpLiveRange(Item, Func);
991*03ce13f7SAndroid Build Coastguard Worker Str << "\n";
992*03ce13f7SAndroid Build Coastguard Worker }
993*03ce13f7SAndroid Build Coastguard Worker Str << "++++++ Active:\n";
994*03ce13f7SAndroid Build Coastguard Worker for (const Variable *Item : Active) {
995*03ce13f7SAndroid Build Coastguard Worker dumpLiveRange(Item, Func);
996*03ce13f7SAndroid Build Coastguard Worker Str << "\n";
997*03ce13f7SAndroid Build Coastguard Worker }
998*03ce13f7SAndroid Build Coastguard Worker Str << "++++++ Inactive:\n";
999*03ce13f7SAndroid Build Coastguard Worker for (const Variable *Item : Inactive) {
1000*03ce13f7SAndroid Build Coastguard Worker dumpLiveRange(Item, Func);
1001*03ce13f7SAndroid Build Coastguard Worker Str << "\n";
1002*03ce13f7SAndroid Build Coastguard Worker }
1003*03ce13f7SAndroid Build Coastguard Worker }
1004*03ce13f7SAndroid Build Coastguard Worker
1005*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice
1006