blob: 348f25618145db411bfe32f08c40142381eba2ef [file] [log] [blame]
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001//===- subzero/src/IceRegAlloc.cpp - Linear-scan implementation -----------===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Implements the LinearScan class, which performs the linear-scan
Andrew Sculld24cfda2015-08-25 10:31:15 -070012/// register allocation after liveness analysis has been performed.
Andrew Scull9612d322015-07-06 14:53:25 -070013///
Jim Stichnothd97c7df2014-06-04 11:57:08 -070014//===----------------------------------------------------------------------===//
15
John Porto67f8de92015-06-25 10:14:17 -070016#include "IceRegAlloc.h"
17
John Portoe82b5602016-02-24 15:58:55 -080018#include "IceBitVector.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070019#include "IceCfg.h"
Jim Stichnoth87ff3a12014-11-14 10:27:29 -080020#include "IceCfgNode.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070021#include "IceInst.h"
John Portoec3f5652015-08-31 15:07:09 -070022#include "IceInstVarIter.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070023#include "IceOperand.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070024#include "IceTargetLowering.h"
25
Jim Stichnoth11756b52016-04-06 12:20:18 -070026#include "llvm/Support/Format.h"
27
Jim Stichnothd97c7df2014-06-04 11:57:08 -070028namespace Ice {
29
Jim Stichnothad403532014-09-25 12:44:17 -070030namespace {
31
32// Returns true if Var has any definitions within Item's live range.
Andrew Sculld24cfda2015-08-25 10:31:15 -070033// TODO(stichnot): Consider trimming the Definitions list similar to how the
34// live ranges are trimmed, since all the overlapsDefs() tests are whether some
35// variable's definitions overlap Cur, and trimming is with respect Cur.start.
36// Initial tests show no measurable performance difference, so we'll keep the
37// code simple for now.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070038bool overlapsDefs(const Cfg *Func, const Variable *Item, const Variable *Var) {
Jim Stichnotha3f57b92015-07-30 12:46:04 -070039 constexpr bool UseTrimmed = true;
Jim Stichnoth037fa1d2014-10-07 11:09:33 -070040 VariablesMetadata *VMetadata = Func->getVMetadata();
Jim Stichnoth877b04e2014-10-15 15:13:06 -070041 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var))
42 if (Item->getLiveRange().overlapsInst(FirstDef->getNumber(), UseTrimmed))
43 return true;
Jim Stichnoth48e3ae52015-10-01 13:33:35 -070044 for (const Inst *Def : VMetadata->getLatterDefinitions(Var)) {
45 if (Item->getLiveRange().overlapsInst(Def->getNumber(), UseTrimmed))
Jim Stichnothad403532014-09-25 12:44:17 -070046 return true;
47 }
48 return false;
49}
50
51void dumpDisableOverlap(const Cfg *Func, const Variable *Var,
52 const char *Reason) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -070053 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -080054 return;
Jim Stichnotha1da6ff2015-11-16 15:59:39 -080055 if (!Func->isVerbose(IceV_LinearScan))
56 return;
57
58 VariablesMetadata *VMetadata = Func->getVMetadata();
59 Ostream &Str = Func->getContext()->getStrDump();
60 Str << "Disabling Overlap due to " << Reason << " " << *Var
61 << " LIVE=" << Var->getLiveRange() << " Defs=";
62 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var))
63 Str << FirstDef->getNumber();
64 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var);
65 for (size_t i = 0; i < Defs.size(); ++i) {
66 Str << "," << Defs[i]->getNumber();
Jim Stichnothad403532014-09-25 12:44:17 -070067 }
Jim Stichnotha1da6ff2015-11-16 15:59:39 -080068 Str << "\n";
Jim Stichnothad403532014-09-25 12:44:17 -070069}
70
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070071void dumpLiveRange(const Variable *Var, const Cfg *Func) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -070072 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -080073 return;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070074 Ostream &Str = Func->getContext()->getStrDump();
Jim Stichnoth11756b52016-04-06 12:20:18 -070075 Str << "R=";
76 if (Var->hasRegTmp()) {
Jim Stichnoth79810752016-12-26 14:16:00 -080077 Str << llvm::format("%2d", int(Var->getRegNumTmp()));
Jim Stichnoth11756b52016-04-06 12:20:18 -070078 } else {
79 Str << "NA";
80 }
81 Str << " V=";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070082 Var->dump(Func);
83 Str << " Range=" << Var->getLiveRange();
Jim Stichnothe22f8232014-10-13 16:20:59 -070084}
85
Jim Stichnothb40595a2016-01-29 06:14:31 -080086int32_t findMinWeightIndex(
John Portoe82b5602016-02-24 15:58:55 -080087 const SmallBitVector &RegMask,
Jim Stichnothb40595a2016-01-29 06:14:31 -080088 const llvm::SmallVector<RegWeight, LinearScan::REGS_SIZE> &Weights) {
Jim Stichnoth8aa39662016-02-10 11:20:30 -080089 int MinWeightIndex = -1;
90 for (RegNumT i : RegNumBVIter(RegMask)) {
91 if (MinWeightIndex < 0 || Weights[i] < Weights[MinWeightIndex])
Jim Stichnothb40595a2016-01-29 06:14:31 -080092 MinWeightIndex = i;
93 }
Jim Stichnoth2655d962016-04-21 05:38:15 -070094 assert(getFlags().getRegAllocReserve() || MinWeightIndex >= 0);
Jim Stichnothb40595a2016-01-29 06:14:31 -080095 return MinWeightIndex;
96}
97
Jim Stichnothad403532014-09-25 12:44:17 -070098} // end of anonymous namespace
99
Andrew Sculld24cfda2015-08-25 10:31:15 -0700100LinearScan::LinearScan(Cfg *Func)
John Portobb0a5fe2015-09-04 11:23:41 -0700101 : Func(Func), Ctx(Func->getContext()), Target(Func->getTarget()),
Jim Stichnothb40595a2016-01-29 06:14:31 -0800102 Verbose(BuildDefs::dump() && Func->isVerbose(IceV_LinearScan)),
Karl Schimpfd4699942016-04-02 09:55:31 -0700103 UseReserve(getFlags().getRegAllocReserve()) {}
Andrew Sculld24cfda2015-08-25 10:31:15 -0700104
Andrew Scull57e12682015-09-16 11:30:19 -0700105// Prepare for full register allocation of all variables. We depend on liveness
106// analysis to have calculated live ranges.
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800107void LinearScan::initForGlobal() {
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800108 TimerMarker T(TimerStack::TT_initUnhandled, Func);
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800109 FindPreference = true;
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700110 // For full register allocation, normally we want to enable FindOverlap
111 // (meaning we look for opportunities for two overlapping live ranges to
Andrew Scull57e12682015-09-16 11:30:19 -0700112 // safely share the same register). However, we disable it for phi-lowering
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700113 // register allocation since no overlap opportunities should be available and
114 // it's more expensive to look for opportunities.
115 FindOverlap = (Kind != RAK_Phi);
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800116 Unhandled.reserve(Vars.size());
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800117 UnhandledPrecolored.reserve(Vars.size());
Andrew Sculld24cfda2015-08-25 10:31:15 -0700118 // Gather the live ranges of all variables and add them to the Unhandled set.
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800119 for (Variable *Var : Vars) {
Jim Stichnoth4c5c5712015-11-16 17:17:48 -0800120 // Don't consider rematerializable variables.
121 if (Var->isRematerializable())
122 continue;
Andrew Sculld24cfda2015-08-25 10:31:15 -0700123 // Explicitly don't consider zero-weight variables, which are meant to be
124 // spill slots.
Andrew Scull11c9a322015-08-28 14:24:14 -0700125 if (Var->mustNotHaveReg())
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800126 continue;
Andrew Sculld24cfda2015-08-25 10:31:15 -0700127 // Don't bother if the variable has a null live range, which means it was
128 // never referenced.
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800129 if (Var->getLiveRange().isEmpty())
130 continue;
131 Var->untrimLiveRange();
132 Unhandled.push_back(Var);
133 if (Var->hasReg()) {
134 Var->setRegNumTmp(Var->getRegNum());
Andrew Scull11c9a322015-08-28 14:24:14 -0700135 Var->setMustHaveReg();
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800136 UnhandledPrecolored.push_back(Var);
137 }
138 }
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800139
140 // Build the (ordered) list of FakeKill instruction numbers.
141 Kills.clear();
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700142 // Phi lowering should not be creating new call instructions, so there should
143 // be no infinite-weight not-yet-colored live ranges that span a call
144 // instruction, hence no need to construct the Kills list.
145 if (Kind == RAK_Phi)
146 return;
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800147 for (CfgNode *Node : Func->getNodes()) {
Jim Stichnoth29841e82014-12-23 12:26:24 -0800148 for (Inst &I : Node->getInsts()) {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700149 if (auto *Kill = llvm::dyn_cast<InstFakeKill>(&I)) {
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800150 if (!Kill->isDeleted() && !Kill->getLinked()->isDeleted())
Jim Stichnoth29841e82014-12-23 12:26:24 -0800151 Kills.push_back(I.getNumber());
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800152 }
153 }
154 }
155}
156
Jim Stichnoth230d4102015-09-25 17:40:32 -0700157// Validate the integrity of the live ranges. If there are any errors, it
158// prints details and returns false. On success, it returns true.
159bool LinearScan::livenessValidateIntervals(
160 const DefUseErrorList &DefsWithoutUses,
161 const DefUseErrorList &UsesBeforeDefs,
162 const CfgVector<InstNumberT> &LRBegin,
Jim Stichnoth318f4cd2015-10-01 21:02:37 -0700163 const CfgVector<InstNumberT> &LREnd) const {
Jim Stichnoth230d4102015-09-25 17:40:32 -0700164 if (DefsWithoutUses.empty() && UsesBeforeDefs.empty())
165 return true;
166
167 if (!BuildDefs::dump())
168 return false;
169
Jim Stichnoth230d4102015-09-25 17:40:32 -0700170 OstreamLocker L(Ctx);
171 Ostream &Str = Ctx->getStrDump();
172 for (SizeT VarNum : DefsWithoutUses) {
173 Variable *Var = Vars[VarNum];
174 Str << "LR def without use, instruction " << LRBegin[VarNum]
Jim Stichnotha91c3412016-04-05 15:31:43 -0700175 << ", variable " << Var->getName() << "\n";
Jim Stichnoth230d4102015-09-25 17:40:32 -0700176 }
177 for (SizeT VarNum : UsesBeforeDefs) {
178 Variable *Var = Vars[VarNum];
179 Str << "LR use before def, instruction " << LREnd[VarNum] << ", variable "
Jim Stichnotha91c3412016-04-05 15:31:43 -0700180 << Var->getName() << "\n";
Jim Stichnoth230d4102015-09-25 17:40:32 -0700181 }
182 return false;
183}
184
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800185// Prepare for very simple register allocation of only infinite-weight Variables
186// while respecting pre-colored Variables. Some properties we take advantage of:
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800187//
188// * Live ranges of interest consist of a single segment.
189//
190// * Live ranges of interest never span a call instruction.
191//
Andrew Sculld24cfda2015-08-25 10:31:15 -0700192// * Phi instructions are not considered because either phis have already been
193// lowered, or they don't contain any pre-colored or infinite-weight
194// Variables.
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800195//
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800196// * We don't need to renumber instructions before computing live ranges because
197// all the high-level ICE instructions are deleted prior to lowering, and the
198// low-level instructions are added in monotonically increasing order.
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800199//
Andrew Sculld24cfda2015-08-25 10:31:15 -0700200// * There are no opportunities for register preference or allowing overlap.
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800201//
202// Some properties we aren't (yet) taking advantage of:
203//
Andrew Sculld24cfda2015-08-25 10:31:15 -0700204// * Because live ranges are a single segment, the Inactive set will always be
205// empty, and the live range trimming operation is unnecessary.
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800206//
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800207// * Calculating overlap of single-segment live ranges could be optimized a bit.
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800208void LinearScan::initForInfOnly() {
209 TimerMarker T(TimerStack::TT_initUnhandled, Func);
210 FindPreference = false;
211 FindOverlap = false;
212 SizeT NumVars = 0;
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800213
Andrew Sculld24cfda2015-08-25 10:31:15 -0700214 // Iterate across all instructions and record the begin and end of the live
215 // range for each variable that is pre-colored or infinite weight.
Andrew Scull00741a02015-09-16 19:04:09 -0700216 CfgVector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel);
217 CfgVector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel);
Jim Stichnoth230d4102015-09-25 17:40:32 -0700218 DefUseErrorList DefsWithoutUses, UsesBeforeDefs;
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800219 for (CfgNode *Node : Func->getNodes()) {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800220 for (Inst &Instr : Node->getInsts()) {
221 if (Instr.isDeleted())
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800222 continue;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800223 FOREACH_VAR_IN_INST(Var, Instr) {
Jim Stichnoth230d4102015-09-25 17:40:32 -0700224 if (Var->getIgnoreLiveness())
225 continue;
226 if (Var->hasReg() || Var->mustHaveReg()) {
227 SizeT VarNum = Var->getIndex();
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800228 LREnd[VarNum] = Instr.getNumber();
Jim Stichnoth230d4102015-09-25 17:40:32 -0700229 if (!Var->getIsArg() && LRBegin[VarNum] == Inst::NumberSentinel)
230 UsesBeforeDefs.push_back(VarNum);
231 }
232 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800233 if (const Variable *Var = Instr.getDest()) {
Jim Stichnothcc89c952016-03-31 11:55:23 -0700234 if (!Var->getIgnoreLiveness() &&
Andrew Scull11c9a322015-08-28 14:24:14 -0700235 (Var->hasReg() || Var->mustHaveReg())) {
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800236 if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800237 LRBegin[Var->getIndex()] = Instr.getNumber();
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800238 ++NumVars;
239 }
240 }
241 }
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800242 }
243 }
244
245 Unhandled.reserve(NumVars);
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800246 UnhandledPrecolored.reserve(NumVars);
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800247 for (SizeT i = 0; i < Vars.size(); ++i) {
248 Variable *Var = Vars[i];
Jim Stichnoth4c5c5712015-11-16 17:17:48 -0800249 if (Var->isRematerializable())
250 continue;
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800251 if (LRBegin[i] != Inst::NumberSentinel) {
Jim Stichnoth230d4102015-09-25 17:40:32 -0700252 if (LREnd[i] == Inst::NumberSentinel) {
253 DefsWithoutUses.push_back(i);
254 continue;
255 }
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800256 Unhandled.push_back(Var);
257 Var->resetLiveRange();
Andrew Scull11c9a322015-08-28 14:24:14 -0700258 Var->addLiveRange(LRBegin[i], LREnd[i]);
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800259 Var->untrimLiveRange();
260 if (Var->hasReg()) {
261 Var->setRegNumTmp(Var->getRegNum());
Andrew Scull11c9a322015-08-28 14:24:14 -0700262 Var->setMustHaveReg();
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800263 UnhandledPrecolored.push_back(Var);
264 }
265 --NumVars;
266 }
267 }
Jim Stichnoth230d4102015-09-25 17:40:32 -0700268
269 if (!livenessValidateIntervals(DefsWithoutUses, UsesBeforeDefs, LRBegin,
270 LREnd)) {
271 llvm::report_fatal_error("initForInfOnly: Liveness error");
272 return;
273 }
274
275 if (!DefsWithoutUses.empty() || !UsesBeforeDefs.empty()) {
276 if (BuildDefs::dump()) {
277 OstreamLocker L(Ctx);
278 Ostream &Str = Ctx->getStrDump();
279 for (SizeT VarNum : DefsWithoutUses) {
280 Variable *Var = Vars[VarNum];
281 Str << "LR def without use, instruction " << LRBegin[VarNum]
Jim Stichnotha91c3412016-04-05 15:31:43 -0700282 << ", variable " << Var->getName() << "\n";
Jim Stichnoth230d4102015-09-25 17:40:32 -0700283 }
284 for (SizeT VarNum : UsesBeforeDefs) {
285 Variable *Var = Vars[VarNum];
286 Str << "LR use before def, instruction " << LREnd[VarNum]
Jim Stichnotha91c3412016-04-05 15:31:43 -0700287 << ", variable " << Var->getName() << "\n";
Jim Stichnoth230d4102015-09-25 17:40:32 -0700288 }
289 }
290 llvm::report_fatal_error("initForInfOnly: Liveness error");
291 }
Andrew Sculld24cfda2015-08-25 10:31:15 -0700292 // This isn't actually a fatal condition, but it would be nice to know if we
293 // somehow pre-calculated Unhandled's size wrong.
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800294 assert(NumVars == 0);
295
Andrew Sculld24cfda2015-08-25 10:31:15 -0700296 // Don't build up the list of Kills because we know that no infinite-weight
297 // Variable has a live range spanning a call.
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800298 Kills.clear();
299}
300
Jim Stichnoth4001c932015-10-09 14:33:26 -0700301void LinearScan::initForSecondChance() {
302 TimerMarker T(TimerStack::TT_initUnhandled, Func);
303 FindPreference = true;
304 FindOverlap = true;
305 const VarList &Vars = Func->getVariables();
306 Unhandled.reserve(Vars.size());
307 UnhandledPrecolored.reserve(Vars.size());
308 for (Variable *Var : Vars) {
Jim Stichnoth4c5c5712015-11-16 17:17:48 -0800309 if (Var->isRematerializable())
310 continue;
Jim Stichnoth4001c932015-10-09 14:33:26 -0700311 if (Var->hasReg()) {
312 Var->untrimLiveRange();
313 Var->setRegNumTmp(Var->getRegNum());
314 Var->setMustHaveReg();
315 UnhandledPrecolored.push_back(Var);
316 Unhandled.push_back(Var);
317 }
318 }
319 for (Variable *Var : Evicted) {
320 Var->untrimLiveRange();
321 Unhandled.push_back(Var);
322 }
323}
324
Manasij Mukherjee7cd926d2016-08-04 12:33:23 -0700325void LinearScan::init(RegAllocKind Kind, CfgSet<Variable *> ExcludeVars) {
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700326 this->Kind = Kind;
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800327 Unhandled.clear();
328 UnhandledPrecolored.clear();
329 Handled.clear();
330 Inactive.clear();
331 Active.clear();
Manasij Mukherjee7cd926d2016-08-04 12:33:23 -0700332 Vars.clear();
333 Vars.reserve(Func->getVariables().size() - ExcludeVars.size());
334 for (auto *Var : Func->getVariables()) {
335 if (ExcludeVars.find(Var) == ExcludeVars.end())
336 Vars.emplace_back(Var);
337 }
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800338
John Portobb0a5fe2015-09-04 11:23:41 -0700339 SizeT NumRegs = Target->getNumRegisters();
340 RegAliases.resize(NumRegs);
341 for (SizeT Reg = 0; Reg < NumRegs; ++Reg) {
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800342 RegAliases[Reg] = &Target->getAliasesForRegister(RegNumT::fromInt(Reg));
John Portobb0a5fe2015-09-04 11:23:41 -0700343 }
344
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800345 switch (Kind) {
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700346 case RAK_Unknown:
347 llvm::report_fatal_error("Invalid RAK_Unknown");
348 break;
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800349 case RAK_Global:
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700350 case RAK_Phi:
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800351 initForGlobal();
352 break;
353 case RAK_InfOnly:
354 initForInfOnly();
355 break;
Jim Stichnoth4001c932015-10-09 14:33:26 -0700356 case RAK_SecondChance:
357 initForSecondChance();
358 break;
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800359 }
360
Jim Stichnoth4001c932015-10-09 14:33:26 -0700361 Evicted.clear();
362
Jim Stichnoth992f91d2015-08-10 11:18:38 -0700363 auto CompareRanges = [](const Variable *L, const Variable *R) {
Qining Luaee5fa82015-08-20 14:59:03 -0700364 InstNumberT Lstart = L->getLiveRange().getStart();
365 InstNumberT Rstart = R->getLiveRange().getStart();
366 if (Lstart == Rstart)
367 return L->getIndex() < R->getIndex();
368 return Lstart < Rstart;
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800369 };
370 // Do a reverse sort so that erasing elements (from the end) is fast.
Jim Stichnoth992f91d2015-08-10 11:18:38 -0700371 std::sort(Unhandled.rbegin(), Unhandled.rend(), CompareRanges);
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800372 std::sort(UnhandledPrecolored.rbegin(), UnhandledPrecolored.rend(),
Jim Stichnoth992f91d2015-08-10 11:18:38 -0700373 CompareRanges);
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800374
375 Handled.reserve(Unhandled.size());
376 Inactive.reserve(Unhandled.size());
377 Active.reserve(Unhandled.size());
Jim Stichnoth4001c932015-10-09 14:33:26 -0700378 Evicted.reserve(Unhandled.size());
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800379}
380
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700381// This is called when Cur must be allocated a register but no registers are
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800382// available across Cur's live range. To handle this, we find a register that is
383// not explicitly used during Cur's live range, spill that register to a stack
384// location right before Cur's live range begins, and fill (reload) the register
385// from the stack location right after Cur's live range ends.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700386void LinearScan::addSpillFill(IterationState &Iter) {
387 // Identify the actual instructions that begin and end Iter.Cur's live range.
388 // Iterate through Iter.Cur's node's instruction list until we find the actual
389 // instructions with instruction numbers corresponding to Iter.Cur's recorded
390 // live range endpoints. This sounds inefficient but shouldn't be a problem
391 // in practice because:
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700392 // (1) This function is almost never called in practice.
393 // (2) Since this register over-subscription problem happens only for
394 // phi-lowered instructions, the number of instructions in the node is
395 // proportional to the number of phi instructions in the original node,
396 // which is never very large in practice.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700397 // (3) We still have to iterate through all instructions of Iter.Cur's live
398 // range to find all explicitly used registers (though the live range is
399 // usually only 2-3 instructions), so the main cost that could be avoided
400 // would be finding the instruction that begin's Iter.Cur's live range.
401 assert(!Iter.Cur->getLiveRange().isEmpty());
402 InstNumberT Start = Iter.Cur->getLiveRange().getStart();
403 InstNumberT End = Iter.Cur->getLiveRange().getEnd();
404 CfgNode *Node = Func->getVMetadata()->getLocalUseNode(Iter.Cur);
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700405 assert(Node);
406 InstList &Insts = Node->getInsts();
407 InstList::iterator SpillPoint = Insts.end();
408 InstList::iterator FillPoint = Insts.end();
409 // Stop searching after we have found both the SpillPoint and the FillPoint.
410 for (auto I = Insts.begin(), E = Insts.end();
411 I != E && (SpillPoint == E || FillPoint == E); ++I) {
412 if (I->getNumber() == Start)
413 SpillPoint = I;
414 if (I->getNumber() == End)
415 FillPoint = I;
416 if (SpillPoint != E) {
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800417 // Remove from RegMask any physical registers referenced during Cur's live
418 // range. Start looking after SpillPoint gets set, i.e. once Cur's live
419 // range begins.
John Portoec3f5652015-08-31 15:07:09 -0700420 FOREACH_VAR_IN_INST(Var, *I) {
John Portobb0a5fe2015-09-04 11:23:41 -0700421 if (!Var->hasRegTmp())
422 continue;
John Portoe82b5602016-02-24 15:58:55 -0800423 const auto &Aliases = *RegAliases[Var->getRegNumTmp()];
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800424 for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
John Portobb0a5fe2015-09-04 11:23:41 -0700425 Iter.RegMask[RegAlias] = false;
426 }
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700427 }
428 }
429 }
430 assert(SpillPoint != Insts.end());
431 assert(FillPoint != Insts.end());
432 ++FillPoint;
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800433 // TODO(stichnot): Randomize instead of *.begin() which maps to find_first().
434 const RegNumT RegNum = *RegNumBVIter(Iter.RegMask).begin();
Andrew Sculld24cfda2015-08-25 10:31:15 -0700435 Iter.Cur->setRegNumTmp(RegNum);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700436 Variable *Preg = Target->getPhysicalRegister(RegNum, Iter.Cur->getType());
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800437 // TODO(stichnot): Add SpillLoc to VariablesMetadata tracking so that SpillLoc
438 // is correctly identified as !isMultiBlock(), reducing stack frame size.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700439 Variable *SpillLoc = Func->makeVariable(Iter.Cur->getType());
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700440 // Add "reg=FakeDef;spill=reg" before SpillPoint
441 Target->lowerInst(Node, SpillPoint, InstFakeDef::create(Func, Preg));
442 Target->lowerInst(Node, SpillPoint, InstAssign::create(Func, SpillLoc, Preg));
443 // add "reg=spill;FakeUse(reg)" before FillPoint
444 Target->lowerInst(Node, FillPoint, InstAssign::create(Func, Preg, SpillLoc));
445 Target->lowerInst(Node, FillPoint, InstFakeUse::create(Func, Preg));
446}
447
Andrew Sculld24cfda2015-08-25 10:31:15 -0700448void LinearScan::handleActiveRangeExpiredOrInactive(const Variable *Cur) {
449 for (SizeT I = Active.size(); I > 0; --I) {
450 const SizeT Index = I - 1;
451 Variable *Item = Active[Index];
452 Item->trimLiveRange(Cur->getLiveRange().getStart());
453 bool Moved = false;
454 if (Item->rangeEndsBefore(Cur)) {
455 // Move Item from Active to Handled list.
Jim Stichnoth69660552015-09-18 06:41:02 -0700456 dumpLiveRangeTrace("Expiring ", Item);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700457 moveItem(Active, Index, Handled);
458 Moved = true;
459 } else if (!Item->rangeOverlapsStart(Cur)) {
460 // Move Item from Active to Inactive list.
Jim Stichnoth69660552015-09-18 06:41:02 -0700461 dumpLiveRangeTrace("Inactivating ", Item);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700462 moveItem(Active, Index, Inactive);
463 Moved = true;
464 }
465 if (Moved) {
466 // Decrement Item from RegUses[].
467 assert(Item->hasRegTmp());
John Portoe82b5602016-02-24 15:58:55 -0800468 const auto &Aliases = *RegAliases[Item->getRegNumTmp()];
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800469 for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
John Portobb0a5fe2015-09-04 11:23:41 -0700470 --RegUses[RegAlias];
471 assert(RegUses[RegAlias] >= 0);
472 }
Jim Stichnothe6d24782014-12-19 05:42:24 -0800473 }
474 }
Andrew Sculld24cfda2015-08-25 10:31:15 -0700475}
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700476
Andrew Sculld24cfda2015-08-25 10:31:15 -0700477void LinearScan::handleInactiveRangeExpiredOrReactivated(const Variable *Cur) {
478 for (SizeT I = Inactive.size(); I > 0; --I) {
479 const SizeT Index = I - 1;
480 Variable *Item = Inactive[Index];
481 Item->trimLiveRange(Cur->getLiveRange().getStart());
482 if (Item->rangeEndsBefore(Cur)) {
483 // Move Item from Inactive to Handled list.
Jim Stichnoth69660552015-09-18 06:41:02 -0700484 dumpLiveRangeTrace("Expiring ", Item);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700485 moveItem(Inactive, Index, Handled);
486 } else if (Item->rangeOverlapsStart(Cur)) {
487 // Move Item from Inactive to Active list.
Jim Stichnoth69660552015-09-18 06:41:02 -0700488 dumpLiveRangeTrace("Reactivating ", Item);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700489 moveItem(Inactive, Index, Active);
490 // Increment Item in RegUses[].
491 assert(Item->hasRegTmp());
John Portoe82b5602016-02-24 15:58:55 -0800492 const auto &Aliases = *RegAliases[Item->getRegNumTmp()];
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800493 for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
John Portobb0a5fe2015-09-04 11:23:41 -0700494 assert(RegUses[RegAlias] >= 0);
495 ++RegUses[RegAlias];
496 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700497 }
Andrew Sculld24cfda2015-08-25 10:31:15 -0700498 }
499}
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700500
Andrew Sculld24cfda2015-08-25 10:31:15 -0700501// Infer register preference and allowable overlap. Only form a preference when
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800502// the current Variable has an unambiguous "first" definition. The preference is
503// some source Variable of the defining instruction that either is assigned a
504// register that is currently free, or that is assigned a register that is not
505// free but overlap is allowed. Overlap is allowed when the Variable under
506// consideration is single-definition, and its definition is a simple assignment
507// - i.e., the register gets copied/aliased but is never modified. Furthermore,
508// overlap is only allowed when preferred Variable definition instructions do
509// not appear within the current Variable's live range.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700510void LinearScan::findRegisterPreference(IterationState &Iter) {
511 Iter.Prefer = nullptr;
Reed Kotler5fa0a5f2016-02-15 20:01:24 -0800512 Iter.PreferReg = RegNumT();
Andrew Sculld24cfda2015-08-25 10:31:15 -0700513 Iter.AllowOverlap = false;
514
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800515 if (!FindPreference)
516 return;
517
518 VariablesMetadata *VMetadata = Func->getVMetadata();
519 const Inst *DefInst = VMetadata->getFirstDefinitionSingleBlock(Iter.Cur);
520 if (DefInst == nullptr)
521 return;
522
523 assert(DefInst->getDest() == Iter.Cur);
524 const bool IsSingleDefAssign =
525 DefInst->isVarAssign() && !VMetadata->isMultiDef(Iter.Cur);
526 FOREACH_VAR_IN_INST(SrcVar, *DefInst) {
527 // Only consider source variables that have (so far) been assigned a
528 // register.
529 if (!SrcVar->hasRegTmp())
530 continue;
531
532 // That register must be one in the RegMask set, e.g. don't try to prefer
533 // the stack pointer as a result of the stacksave intrinsic.
John Portoe82b5602016-02-24 15:58:55 -0800534 const auto &Aliases = *RegAliases[SrcVar->getRegNumTmp()];
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800535 const int SrcReg = (Iter.RegMask & Aliases).find_first();
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800536 if (SrcReg == -1)
537 continue;
538
539 if (FindOverlap && IsSingleDefAssign && !Iter.Free[SrcReg]) {
540 // Don't bother trying to enable AllowOverlap if the register is already
541 // free (hence the test on Iter.Free[SrcReg]).
542 Iter.AllowOverlap = !overlapsDefs(Func, Iter.Cur, SrcVar);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700543 }
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800544 if (Iter.AllowOverlap || Iter.Free[SrcReg]) {
545 Iter.Prefer = SrcVar;
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800546 Iter.PreferReg = RegNumT::fromInt(SrcReg);
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800547 // Stop looking for a preference after the first valid preference is
548 // found. One might think that we should look at all instruction
549 // variables to find the best <Prefer,AllowOverlap> combination, but note
550 // that AllowOverlap can only be true for a simple assignment statement
551 // which can have only one source operand, so it's not possible for
552 // AllowOverlap to be true beyond the first source operand.
553 FOREACH_VAR_IN_INST_BREAK;
554 }
555 }
556 if (BuildDefs::dump() && Verbose && Iter.Prefer) {
557 Ostream &Str = Ctx->getStrDump();
558 Str << "Initial Iter.Prefer=";
559 Iter.Prefer->dump(Func);
560 Str << " R=" << Iter.PreferReg << " LIVE=" << Iter.Prefer->getLiveRange()
561 << " Overlap=" << Iter.AllowOverlap << "\n";
Andrew Sculld24cfda2015-08-25 10:31:15 -0700562 }
563}
564
Jim Stichnothb40595a2016-01-29 06:14:31 -0800565// Remove registers from the Iter.Free[] list where an Inactive range overlaps
566// with the current range.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700567void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) {
568 for (const Variable *Item : Inactive) {
John Portobb0a5fe2015-09-04 11:23:41 -0700569 if (!Item->rangeOverlaps(Iter.Cur))
570 continue;
John Portoe82b5602016-02-24 15:58:55 -0800571 const auto &Aliases = *RegAliases[Item->getRegNumTmp()];
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800572 for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
573 // Don't assert(Iter.Free[RegAlias]) because in theory (though probably
Jim Stichnothb40595a2016-01-29 06:14:31 -0800574 // never in practice) there could be two inactive variables that were
575 // marked with AllowOverlap.
John Portobb0a5fe2015-09-04 11:23:41 -0700576 Iter.Free[RegAlias] = false;
Jim Stichnothb40595a2016-01-29 06:14:31 -0800577 Iter.FreeUnfiltered[RegAlias] = false;
Andrew Sculld24cfda2015-08-25 10:31:15 -0700578 // Disable AllowOverlap if an Inactive variable, which is not Prefer,
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800579 // shares Prefer's register, and has a definition within Cur's live range.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700580 if (Iter.AllowOverlap && Item != Iter.Prefer &&
John Portobb0a5fe2015-09-04 11:23:41 -0700581 RegAlias == Iter.PreferReg && overlapsDefs(Func, Iter.Cur, Item)) {
Andrew Sculld24cfda2015-08-25 10:31:15 -0700582 Iter.AllowOverlap = false;
583 dumpDisableOverlap(Func, Item, "Inactive");
584 }
585 }
586 }
587}
588
Jim Stichnothb40595a2016-01-29 06:14:31 -0800589// Remove registers from the Iter.Free[] list where an Unhandled pre-colored
590// range overlaps with the current range, and set those registers to infinite
591// weight so that they aren't candidates for eviction.
592// Cur->rangeEndsBefore(Item) is an early exit check that turns a guaranteed
593// O(N^2) algorithm into expected linear complexity.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700594void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) {
Jim Stichnoth4c5c5712015-11-16 17:17:48 -0800595 // TODO(stichnot): Partition UnhandledPrecolored according to register class,
596 // to restrict the number of overlap comparisons needed.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700597 for (Variable *Item : reverse_range(UnhandledPrecolored)) {
598 assert(Item->hasReg());
599 if (Iter.Cur->rangeEndsBefore(Item))
600 break;
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800601 if (!Item->rangeOverlaps(Iter.Cur))
602 continue;
John Portoe82b5602016-02-24 15:58:55 -0800603 const auto &Aliases =
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800604 *RegAliases[Item->getRegNum()]; // Note: not getRegNumTmp()
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800605 for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800606 Iter.Weights[RegAlias].setWeight(RegWeight::Inf);
607 Iter.Free[RegAlias] = false;
Jim Stichnothb40595a2016-01-29 06:14:31 -0800608 Iter.FreeUnfiltered[RegAlias] = false;
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800609 Iter.PrecoloredUnhandledMask[RegAlias] = true;
610 // Disable Iter.AllowOverlap if the preferred register is one of these
611 // pre-colored unhandled overlapping ranges.
612 if (Iter.AllowOverlap && RegAlias == Iter.PreferReg) {
613 Iter.AllowOverlap = false;
614 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled");
Andrew Sculld24cfda2015-08-25 10:31:15 -0700615 }
616 }
617 }
618}
619
620void LinearScan::allocatePrecoloredRegister(Variable *Cur) {
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800621 const auto RegNum = Cur->getRegNum();
Andrew Sculld24cfda2015-08-25 10:31:15 -0700622 // RegNumTmp should have already been set above.
623 assert(Cur->getRegNumTmp() == RegNum);
624 dumpLiveRangeTrace("Precoloring ", Cur);
625 Active.push_back(Cur);
John Portoe82b5602016-02-24 15:58:55 -0800626 const auto &Aliases = *RegAliases[RegNum];
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800627 for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
John Portobb0a5fe2015-09-04 11:23:41 -0700628 assert(RegUses[RegAlias] >= 0);
629 ++RegUses[RegAlias];
630 }
Andrew Sculld24cfda2015-08-25 10:31:15 -0700631 assert(!UnhandledPrecolored.empty());
632 assert(UnhandledPrecolored.back() == Cur);
633 UnhandledPrecolored.pop_back();
634}
635
636void LinearScan::allocatePreferredRegister(IterationState &Iter) {
637 Iter.Cur->setRegNumTmp(Iter.PreferReg);
638 dumpLiveRangeTrace("Preferring ", Iter.Cur);
John Portoe82b5602016-02-24 15:58:55 -0800639 const auto &Aliases = *RegAliases[Iter.PreferReg];
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800640 for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
John Portobb0a5fe2015-09-04 11:23:41 -0700641 assert(RegUses[RegAlias] >= 0);
642 ++RegUses[RegAlias];
643 }
Andrew Sculld24cfda2015-08-25 10:31:15 -0700644 Active.push_back(Iter.Cur);
645}
646
Jim Stichnothb40595a2016-01-29 06:14:31 -0800647void LinearScan::allocateFreeRegister(IterationState &Iter, bool Filtered) {
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800648 const RegNumT RegNum =
649 *RegNumBVIter(Filtered ? Iter.Free : Iter.FreeUnfiltered).begin();
Andrew Sculld24cfda2015-08-25 10:31:15 -0700650 Iter.Cur->setRegNumTmp(RegNum);
Jim Stichnothb40595a2016-01-29 06:14:31 -0800651 if (Filtered)
John Porto4b6e4b42016-02-17 05:00:59 -0800652 dumpLiveRangeTrace("Allocating Y ", Iter.Cur);
Jim Stichnothb40595a2016-01-29 06:14:31 -0800653 else
654 dumpLiveRangeTrace("Allocating X ", Iter.Cur);
John Portoe82b5602016-02-24 15:58:55 -0800655 const auto &Aliases = *RegAliases[RegNum];
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800656 for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
John Portobb0a5fe2015-09-04 11:23:41 -0700657 assert(RegUses[RegAlias] >= 0);
658 ++RegUses[RegAlias];
659 }
Andrew Sculld24cfda2015-08-25 10:31:15 -0700660 Active.push_back(Iter.Cur);
661}
662
663void LinearScan::handleNoFreeRegisters(IterationState &Iter) {
664 // Check Active ranges.
665 for (const Variable *Item : Active) {
666 assert(Item->rangeOverlaps(Iter.Cur));
Andrew Sculld24cfda2015-08-25 10:31:15 -0700667 assert(Item->hasRegTmp());
John Portoe82b5602016-02-24 15:58:55 -0800668 const auto &Aliases = *RegAliases[Item->getRegNumTmp()];
John Portobb0a5fe2015-09-04 11:23:41 -0700669 // We add the Item's weight to each alias/subregister to represent that,
670 // should we decide to pick any of them, then we would incur that many
671 // memory accesses.
672 RegWeight W = Item->getWeight(Func);
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800673 for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
John Portobb0a5fe2015-09-04 11:23:41 -0700674 Iter.Weights[RegAlias].addWeight(W);
675 }
Andrew Sculld24cfda2015-08-25 10:31:15 -0700676 }
677 // Same as above, but check Inactive ranges instead of Active.
678 for (const Variable *Item : Inactive) {
John Portobb0a5fe2015-09-04 11:23:41 -0700679 if (!Item->rangeOverlaps(Iter.Cur))
680 continue;
Andrew Sculld24cfda2015-08-25 10:31:15 -0700681 assert(Item->hasRegTmp());
John Portoe82b5602016-02-24 15:58:55 -0800682 const auto &Aliases = *RegAliases[Item->getRegNumTmp()];
John Portobb0a5fe2015-09-04 11:23:41 -0700683 RegWeight W = Item->getWeight(Func);
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800684 for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
John Portobb0a5fe2015-09-04 11:23:41 -0700685 Iter.Weights[RegAlias].addWeight(W);
686 }
Andrew Sculld24cfda2015-08-25 10:31:15 -0700687 }
688
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800689 // All the weights are now calculated. Find the register with smallest weight.
Jim Stichnothb40595a2016-01-29 06:14:31 -0800690 int32_t MinWeightIndex = findMinWeightIndex(Iter.RegMask, Iter.Weights);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700691
Jim Stichnoth2655d962016-04-21 05:38:15 -0700692 if (MinWeightIndex < 0 ||
693 Iter.Cur->getWeight(Func) <= Iter.Weights[MinWeightIndex]) {
Jim Stichnothb40595a2016-01-29 06:14:31 -0800694 if (!Iter.Cur->mustHaveReg()) {
695 // Iter.Cur doesn't have priority over any other live ranges, so don't
696 // allocate any register to it, and move it to the Handled state.
697 Handled.push_back(Iter.Cur);
698 return;
699 }
700 if (Kind == RAK_Phi) {
701 // Iter.Cur is infinite-weight but all physical registers are already
702 // taken, so we need to force one to be temporarily available.
703 addSpillFill(Iter);
704 Handled.push_back(Iter.Cur);
705 return;
706 }
707 // The remaining portion of the enclosing "if" block should only be
708 // reachable if we are manually limiting physical registers for testing.
709 if (UseReserve) {
710 if (Iter.FreeUnfiltered.any()) {
711 // There is some available physical register held in reserve, so use it.
712 constexpr bool NotFiltered = false;
713 allocateFreeRegister(Iter, NotFiltered);
714 // Iter.Cur is now on the Active list.
715 return;
Jim Stichnoth2544d4d2016-01-22 13:07:46 -0800716 }
Jim Stichnothb40595a2016-01-29 06:14:31 -0800717 // At this point, we need to find some reserve register that is already
718 // assigned to a non-infinite-weight variable. This could happen if some
719 // variable was previously assigned an alias of such a register.
720 MinWeightIndex = findMinWeightIndex(Iter.RegMaskUnfiltered, Iter.Weights);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700721 }
Jim Stichnothb40595a2016-01-29 06:14:31 -0800722 if (Iter.Cur->getWeight(Func) <= Iter.Weights[MinWeightIndex]) {
723 dumpLiveRangeTrace("Failing ", Iter.Cur);
724 Func->setError("Unable to find a physical register for an "
725 "infinite-weight live range "
726 "(consider using -reg-reserve): " +
Jim Stichnotha91c3412016-04-05 15:31:43 -0700727 Iter.Cur->getName());
Jim Stichnothb40595a2016-01-29 06:14:31 -0800728 Handled.push_back(Iter.Cur);
729 return;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700730 }
Jim Stichnothb40595a2016-01-29 06:14:31 -0800731 // At this point, MinWeightIndex points to a valid reserve register to
732 // reallocate to Iter.Cur, so drop into the eviction code.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700733 }
Jim Stichnothb40595a2016-01-29 06:14:31 -0800734
735 // Evict all live ranges in Active that register number MinWeightIndex is
736 // assigned to.
John Portoe82b5602016-02-24 15:58:55 -0800737 const auto &Aliases = *RegAliases[MinWeightIndex];
Jim Stichnothb40595a2016-01-29 06:14:31 -0800738 for (SizeT I = Active.size(); I > 0; --I) {
739 const SizeT Index = I - 1;
740 Variable *Item = Active[Index];
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800741 const auto RegNum = Item->getRegNumTmp();
Jim Stichnothb40595a2016-01-29 06:14:31 -0800742 if (Aliases[RegNum]) {
743 dumpLiveRangeTrace("Evicting A ", Item);
John Portoe82b5602016-02-24 15:58:55 -0800744 const auto &Aliases = *RegAliases[RegNum];
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800745 for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
Jim Stichnothb40595a2016-01-29 06:14:31 -0800746 --RegUses[RegAlias];
747 assert(RegUses[RegAlias] >= 0);
748 }
Reed Kotler5fa0a5f2016-02-15 20:01:24 -0800749 Item->setRegNumTmp(RegNumT());
Jim Stichnothb40595a2016-01-29 06:14:31 -0800750 moveItem(Active, Index, Handled);
751 Evicted.push_back(Item);
752 }
753 }
754 // Do the same for Inactive.
755 for (SizeT I = Inactive.size(); I > 0; --I) {
756 const SizeT Index = I - 1;
757 Variable *Item = Inactive[Index];
758 // Note: The Item->rangeOverlaps(Cur) clause is not part of the description
759 // of AssignMemLoc() in the original paper. But there doesn't seem to be any
760 // need to evict an inactive live range that doesn't overlap with the live
761 // range currently being considered. It's especially bad if we would end up
762 // evicting an infinite-weight but currently-inactive live range. The most
763 // common situation for this would be a scratch register kill set for call
764 // instructions.
765 if (Aliases[Item->getRegNumTmp()] && Item->rangeOverlaps(Iter.Cur)) {
766 dumpLiveRangeTrace("Evicting I ", Item);
Reed Kotler5fa0a5f2016-02-15 20:01:24 -0800767 Item->setRegNumTmp(RegNumT());
Jim Stichnothb40595a2016-01-29 06:14:31 -0800768 moveItem(Inactive, Index, Handled);
769 Evicted.push_back(Item);
770 }
771 }
772 // Assign the register to Cur.
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800773 Iter.Cur->setRegNumTmp(RegNumT::fromInt(MinWeightIndex));
774 for (RegNumT RegAlias : RegNumBVIter(Aliases)) {
Jim Stichnothb40595a2016-01-29 06:14:31 -0800775 assert(RegUses[RegAlias] >= 0);
776 ++RegUses[RegAlias];
777 }
778 Active.push_back(Iter.Cur);
John Porto4b6e4b42016-02-17 05:00:59 -0800779 dumpLiveRangeTrace("Allocating Z ", Iter.Cur);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700780}
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700781
John Portoe82b5602016-02-24 15:58:55 -0800782void LinearScan::assignFinalRegisters(const SmallBitVector &RegMaskFull,
783 const SmallBitVector &PreDefinedRegisters,
784 bool Randomized) {
Andrew Sculld24cfda2015-08-25 10:31:15 -0700785 const size_t NumRegisters = RegMaskFull.size();
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800786 llvm::SmallVector<RegNumT, REGS_SIZE> Permutation(NumRegisters);
Jim Stichnothe6d24782014-12-19 05:42:24 -0800787 if (Randomized) {
Qining Luaee5fa82015-08-20 14:59:03 -0700788 // Create a random number generator for regalloc randomization. Merge
Andrew Sculld24cfda2015-08-25 10:31:15 -0700789 // function's sequence and Kind value as the Salt. Because regAlloc() is
Andrew Scull57e12682015-09-16 11:30:19 -0700790 // called twice under O2, the second time with RAK_Phi, we check Kind ==
791 // RAK_Phi to determine the lowest-order bit to make sure the Salt is
792 // different.
Qining Luaee5fa82015-08-20 14:59:03 -0700793 uint64_t Salt =
794 (Func->getSequenceNumber() << 1) ^ (Kind == RAK_Phi ? 0u : 1u);
John Portobb0a5fe2015-09-04 11:23:41 -0700795 Target->makeRandomRegisterPermutation(
Qining Luaee5fa82015-08-20 14:59:03 -0700796 Permutation, PreDefinedRegisters | ~RegMaskFull, Salt);
Jim Stichnothe6d24782014-12-19 05:42:24 -0800797 }
798
Andrew Sculld24cfda2015-08-25 10:31:15 -0700799 // Finish up by setting RegNum = RegNumTmp (or a random permutation thereof)
800 // for each Variable.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700801 for (Variable *Item : Handled) {
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800802 const auto RegNum = Item->getRegNumTmp();
803 auto AssignedRegNum = RegNum;
Jim Stichnothe6d24782014-12-19 05:42:24 -0800804
805 if (Randomized && Item->hasRegTmp() && !Item->hasReg()) {
806 AssignedRegNum = Permutation[RegNum];
807 }
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800808 if (BuildDefs::dump() && Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800809 Ostream &Str = Ctx->getStrDump();
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700810 if (!Item->hasRegTmp()) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700811 Str << "Not assigning ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700812 Item->dump(Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700813 Str << "\n";
814 } else {
Jim Stichnothe6d24782014-12-19 05:42:24 -0800815 Str << (AssignedRegNum == Item->getRegNum() ? "Reassigning "
816 : "Assigning ")
Jim Stichnoth4a659472016-02-01 10:41:18 -0800817 << Target->getRegName(AssignedRegNum, Item->getType()) << "(r"
John Portobb0a5fe2015-09-04 11:23:41 -0700818 << AssignedRegNum << ") to ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700819 Item->dump(Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700820 Str << "\n";
821 }
822 }
Jim Stichnothe6d24782014-12-19 05:42:24 -0800823 Item->setRegNum(AssignedRegNum);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700824 }
Andrew Sculld24cfda2015-08-25 10:31:15 -0700825}
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700826
Andrew Sculld24cfda2015-08-25 10:31:15 -0700827// Implements the linear-scan algorithm. Based on "Linear Scan Register
828// Allocation in the Context of SSA Form and Register Constraints" by Hanspeter
829// Mössenböck and Michael Pfeiffer,
830// ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF. This implementation is
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800831// modified to take affinity into account and allow two interfering variables to
832// share the same register in certain cases.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700833//
834// Requires running Cfg::liveness(Liveness_Intervals) in preparation. Results
835// are assigned to Variable::RegNum for each Variable.
John Portoe82b5602016-02-24 15:58:55 -0800836void LinearScan::scan(const SmallBitVector &RegMaskFull, bool Randomized) {
Andrew Sculld24cfda2015-08-25 10:31:15 -0700837 TimerMarker T(TimerStack::TT_linearScan, Func);
838 assert(RegMaskFull.any()); // Sanity check
839 if (Verbose)
840 Ctx->lockStr();
841 Func->resetCurrentNode();
842 const size_t NumRegisters = RegMaskFull.size();
John Portoe82b5602016-02-24 15:58:55 -0800843 SmallBitVector PreDefinedRegisters(NumRegisters);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700844 if (Randomized) {
845 for (Variable *Var : UnhandledPrecolored) {
846 PreDefinedRegisters[Var->getRegNum()] = true;
847 }
848 }
849
850 // Build a LiveRange representing the Kills list.
851 LiveRange KillsRange(Kills);
852 KillsRange.untrim();
853
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800854 // Reset the register use count.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700855 RegUses.resize(NumRegisters);
856 std::fill(RegUses.begin(), RegUses.end(), 0);
857
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800858 // Unhandled is already set to all ranges in increasing order of start points.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700859 assert(Active.empty());
860 assert(Inactive.empty());
861 assert(Handled.empty());
862 const TargetLowering::RegSetMask RegsInclude =
863 TargetLowering::RegSet_CallerSave;
864 const TargetLowering::RegSetMask RegsExclude = TargetLowering::RegSet_None;
John Portoe82b5602016-02-24 15:58:55 -0800865 const SmallBitVector KillsMask =
John Portobb0a5fe2015-09-04 11:23:41 -0700866 Target->getRegisterSet(RegsInclude, RegsExclude);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700867
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800868 // Allocate memory once outside the loop.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700869 IterationState Iter;
870 Iter.Weights.reserve(NumRegisters);
871 Iter.PrecoloredUnhandledMask.reserve(NumRegisters);
872
873 while (!Unhandled.empty()) {
874 Iter.Cur = Unhandled.back();
875 Unhandled.pop_back();
876 dumpLiveRangeTrace("\nConsidering ", Iter.Cur);
Jim Stichnoth2655d962016-04-21 05:38:15 -0700877 if (UseReserve)
878 assert(Target->getAllRegistersForVariable(Iter.Cur).any());
879 else
880 assert(Target->getRegistersForVariable(Iter.Cur).any());
Jim Stichnothc59288b2015-11-09 11:38:40 -0800881 Iter.RegMask = RegMaskFull & Target->getRegistersForVariable(Iter.Cur);
Jim Stichnothb40595a2016-01-29 06:14:31 -0800882 Iter.RegMaskUnfiltered =
883 RegMaskFull & Target->getAllRegistersForVariable(Iter.Cur);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700884 KillsRange.trim(Iter.Cur->getLiveRange().getStart());
885
886 // Check for pre-colored ranges. If Cur is pre-colored, it definitely gets
887 // that register. Previously processed live ranges would have avoided that
888 // register due to it being pre-colored. Future processed live ranges won't
889 // evict that register because the live range has infinite weight.
890 if (Iter.Cur->hasReg()) {
891 allocatePrecoloredRegister(Iter.Cur);
892 continue;
893 }
894
895 handleActiveRangeExpiredOrInactive(Iter.Cur);
896 handleInactiveRangeExpiredOrReactivated(Iter.Cur);
897
Jim Stichnothb40595a2016-01-29 06:14:31 -0800898 // Calculate available registers into Iter.Free[] and Iter.FreeUnfiltered[].
Andrew Sculld24cfda2015-08-25 10:31:15 -0700899 Iter.Free = Iter.RegMask;
Jim Stichnothb40595a2016-01-29 06:14:31 -0800900 Iter.FreeUnfiltered = Iter.RegMaskUnfiltered;
Andrew Sculld24cfda2015-08-25 10:31:15 -0700901 for (SizeT i = 0; i < Iter.RegMask.size(); ++i) {
Jim Stichnothb40595a2016-01-29 06:14:31 -0800902 if (RegUses[i] > 0) {
Andrew Sculld24cfda2015-08-25 10:31:15 -0700903 Iter.Free[i] = false;
Jim Stichnothb40595a2016-01-29 06:14:31 -0800904 Iter.FreeUnfiltered[i] = false;
905 }
Andrew Sculld24cfda2015-08-25 10:31:15 -0700906 }
907
908 findRegisterPreference(Iter);
909 filterFreeWithInactiveRanges(Iter);
910
911 // Disable AllowOverlap if an Active variable, which is not Prefer, shares
912 // Prefer's register, and has a definition within Cur's live range.
913 if (Iter.AllowOverlap) {
John Portoe82b5602016-02-24 15:58:55 -0800914 const auto &Aliases = *RegAliases[Iter.PreferReg];
Andrew Sculld24cfda2015-08-25 10:31:15 -0700915 for (const Variable *Item : Active) {
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800916 const RegNumT RegNum = Item->getRegNumTmp();
Jim Stichnothc59288b2015-11-09 11:38:40 -0800917 if (Item != Iter.Prefer && Aliases[RegNum] &&
Andrew Sculld24cfda2015-08-25 10:31:15 -0700918 overlapsDefs(Func, Iter.Cur, Item)) {
919 Iter.AllowOverlap = false;
920 dumpDisableOverlap(Func, Item, "Active");
921 }
922 }
923 }
924
925 Iter.Weights.resize(Iter.RegMask.size());
926 std::fill(Iter.Weights.begin(), Iter.Weights.end(), RegWeight());
927
928 Iter.PrecoloredUnhandledMask.resize(Iter.RegMask.size());
929 Iter.PrecoloredUnhandledMask.reset();
930
931 filterFreeWithPrecoloredRanges(Iter);
932
Jim Stichnothb40595a2016-01-29 06:14:31 -0800933 // Remove scratch registers from the Iter.Free[] list, and mark their
934 // Iter.Weights[] as infinite, if KillsRange overlaps Cur's live range.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700935 constexpr bool UseTrimmed = true;
936 if (Iter.Cur->getLiveRange().overlaps(KillsRange, UseTrimmed)) {
937 Iter.Free.reset(KillsMask);
Jim Stichnothb40595a2016-01-29 06:14:31 -0800938 Iter.FreeUnfiltered.reset(KillsMask);
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800939 for (RegNumT i : RegNumBVIter(KillsMask)) {
Andrew Sculld24cfda2015-08-25 10:31:15 -0700940 Iter.Weights[i].setWeight(RegWeight::Inf);
941 if (Iter.PreferReg == i)
942 Iter.AllowOverlap = false;
943 }
944 }
945
946 // Print info about physical register availability.
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800947 if (BuildDefs::dump() && Verbose) {
Andrew Sculld24cfda2015-08-25 10:31:15 -0700948 Ostream &Str = Ctx->getStrDump();
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800949 for (RegNumT i : RegNumBVIter(Iter.RegMaskUnfiltered)) {
950 Str << Target->getRegName(i, Iter.Cur->getType()) << "(U=" << RegUses[i]
951 << ",F=" << Iter.Free[i] << ",P=" << Iter.PrecoloredUnhandledMask[i]
952 << ") ";
Andrew Sculld24cfda2015-08-25 10:31:15 -0700953 }
954 Str << "\n";
955 }
956
957 if (Iter.Prefer && (Iter.AllowOverlap || Iter.Free[Iter.PreferReg])) {
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800958 // First choice: a preferred register that is either free or is allowed to
959 // overlap with its linked variable.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700960 allocatePreferredRegister(Iter);
961 } else if (Iter.Free.any()) {
962 // Second choice: any free register.
Jim Stichnothb40595a2016-01-29 06:14:31 -0800963 constexpr bool Filtered = true;
964 allocateFreeRegister(Iter, Filtered);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700965 } else {
Jim Stichnotha1da6ff2015-11-16 15:59:39 -0800966 // Fallback: there are no free registers, so we look for the lowest-weight
967 // register and see if Cur has higher weight.
Andrew Sculld24cfda2015-08-25 10:31:15 -0700968 handleNoFreeRegisters(Iter);
969 }
970 dump(Func);
971 }
972
973 // Move anything Active or Inactive to Handled for easier handling.
974 Handled.insert(Handled.end(), Active.begin(), Active.end());
975 Active.clear();
976 Handled.insert(Handled.end(), Inactive.begin(), Inactive.end());
977 Inactive.clear();
978 dump(Func);
979
980 assignFinalRegisters(RegMaskFull, PreDefinedRegisters, Randomized);
981
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800982 if (Verbose)
983 Ctx->unlockStr();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700984}
985
986// ======================== Dump routines ======================== //
987
Andrew Sculld24cfda2015-08-25 10:31:15 -0700988void LinearScan::dumpLiveRangeTrace(const char *Label, const Variable *Item) {
989 if (!BuildDefs::dump())
990 return;
991
992 if (Verbose) {
993 Ostream &Str = Ctx->getStrDump();
994 Str << Label;
995 dumpLiveRange(Item, Func);
996 Str << "\n";
997 }
998}
999
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001000void LinearScan::dump(Cfg *Func) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001001 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001002 return;
Jim Stichnotha1da6ff2015-11-16 15:59:39 -08001003 if (!Verbose)
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001004 return;
Jim Stichnothe4a8f402015-01-20 12:52:51 -08001005 Ostream &Str = Func->getContext()->getStrDump();
Jim Stichnoth800dab22014-09-20 12:25:02 -07001006 Func->resetCurrentNode();
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001007 Str << "**** Current regalloc state:\n";
1008 Str << "++++++ Handled:\n";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -07001009 for (const Variable *Item : Handled) {
1010 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001011 Str << "\n";
1012 }
1013 Str << "++++++ Unhandled:\n";
Jim Stichnoth7e571362015-01-09 11:43:26 -08001014 for (const Variable *Item : reverse_range(Unhandled)) {
1015 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001016 Str << "\n";
1017 }
1018 Str << "++++++ Active:\n";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -07001019 for (const Variable *Item : Active) {
1020 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001021 Str << "\n";
1022 }
1023 Str << "++++++ Inactive:\n";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -07001024 for (const Variable *Item : Inactive) {
1025 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001026 Str << "\n";
1027 }
1028}
1029
1030} // end of namespace Ice