xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceRegAlloc.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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