blob: b5c3315c4218636ffe05fa7bb559b265853cf2c4 [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//===----------------------------------------------------------------------===//
9//
10// This file implements the LinearScan class, which performs the
11// linear-scan register allocation after liveness analysis has been
12// performed.
13//
14//===----------------------------------------------------------------------===//
15
16#include "IceCfg.h"
17#include "IceInst.h"
18#include "IceOperand.h"
19#include "IceRegAlloc.h"
20#include "IceTargetLowering.h"
21
22namespace Ice {
23
Jim Stichnothad403532014-09-25 12:44:17 -070024namespace {
25
26// Returns true if Var has any definitions within Item's live range.
Jim Stichnoth037fa1d2014-10-07 11:09:33 -070027// TODO(stichnot): Consider trimming the Definitions list similar to
28// how the live ranges are trimmed, since all the overlapsDefs() tests
29// are whether some variable's definitions overlap Cur, and trimming
30// is with respect Cur.start. Initial tests show no measurable
31// performance difference, so we'll keep the code simple for now.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070032bool overlapsDefs(const Cfg *Func, const Variable *Item, const Variable *Var) {
Jim Stichnoth037fa1d2014-10-07 11:09:33 -070033 const bool UseTrimmed = true;
34 VariablesMetadata *VMetadata = Func->getVMetadata();
35 const InstDefList &Defs = VMetadata->getDefinitions(Var);
Jim Stichnothad403532014-09-25 12:44:17 -070036 for (size_t i = 0; i < Defs.size(); ++i) {
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070037 if (Item->getLiveRange().overlapsInst(Defs[i]->getNumber(), UseTrimmed))
Jim Stichnothad403532014-09-25 12:44:17 -070038 return true;
39 }
40 return false;
41}
42
43void dumpDisableOverlap(const Cfg *Func, const Variable *Var,
44 const char *Reason) {
45 if (Func->getContext()->isVerbose(IceV_LinearScan)) {
Jim Stichnoth037fa1d2014-10-07 11:09:33 -070046 VariablesMetadata *VMetadata = Func->getVMetadata();
Jim Stichnothad403532014-09-25 12:44:17 -070047 Ostream &Str = Func->getContext()->getStrDump();
48 Str << "Disabling Overlap due to " << Reason << " " << *Var
49 << " LIVE=" << Var->getLiveRange() << " Defs=";
Jim Stichnoth037fa1d2014-10-07 11:09:33 -070050 const InstDefList &Defs = VMetadata->getDefinitions(Var);
Jim Stichnothad403532014-09-25 12:44:17 -070051 for (size_t i = 0; i < Defs.size(); ++i) {
52 if (i > 0)
53 Str << ",";
54 Str << Defs[i]->getNumber();
55 }
56 Str << "\n";
57 }
58}
59
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070060void dumpLiveRange(const Variable *Var, const Cfg *Func) {
61 Ostream &Str = Func->getContext()->getStrDump();
62 const static size_t BufLen = 30;
63 char buf[BufLen];
64 snprintf(buf, BufLen, "%2d", Var->getRegNumTmp());
65 Str << "R=" << buf << " V=";
66 Var->dump(Func);
67 Str << " Range=" << Var->getLiveRange();
Jim Stichnothe22f8232014-10-13 16:20:59 -070068}
69
Jim Stichnothad403532014-09-25 12:44:17 -070070} // end of anonymous namespace
71
Jim Stichnothd97c7df2014-06-04 11:57:08 -070072// Implements the linear-scan algorithm. Based on "Linear Scan
73// Register Allocation in the Context of SSA Form and Register
74// Constraints" by Hanspeter Mössenböck and Michael Pfeiffer,
75// ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF . This
76// implementation is modified to take affinity into account and allow
77// two interfering variables to share the same register in certain
78// cases.
79//
Jim Stichnoth800dab22014-09-20 12:25:02 -070080// Requires running Cfg::liveness(Liveness_Intervals) in
Jim Stichnothd97c7df2014-06-04 11:57:08 -070081// preparation. Results are assigned to Variable::RegNum for each
82// Variable.
83void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) {
Jim Stichnoth8363a062014-10-07 10:02:38 -070084 TimerMarker T(TimerStack::TT_linearScan, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -070085 assert(RegMaskFull.any()); // Sanity check
86 Unhandled.clear();
Jim Stichnoth541ba662014-10-02 12:58:21 -070087 UnhandledPrecolored.clear();
Jim Stichnothd97c7df2014-06-04 11:57:08 -070088 Handled.clear();
89 Inactive.clear();
90 Active.clear();
91 Ostream &Str = Func->getContext()->getStrDump();
Jim Stichnothc4554d72014-09-30 16:49:38 -070092 bool Verbose = Func->getContext()->isVerbose(IceV_LinearScan);
Jim Stichnoth800dab22014-09-20 12:25:02 -070093 Func->resetCurrentNode();
Jim Stichnothad403532014-09-25 12:44:17 -070094 VariablesMetadata *VMetadata = Func->getVMetadata();
Jim Stichnothd97c7df2014-06-04 11:57:08 -070095
96 // Gather the live ranges of all variables and add them to the
Jim Stichnothe22f8232014-10-13 16:20:59 -070097 // Unhandled set.
Jim Stichnothd97c7df2014-06-04 11:57:08 -070098 const VarList &Vars = Func->getVariables();
Jim Stichnothc4554d72014-09-30 16:49:38 -070099 {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700100 TimerMarker T(TimerStack::TT_initUnhandled, Func);
Jim Stichnothe22f8232014-10-13 16:20:59 -0700101 Unhandled.reserve(Vars.size());
Jim Stichnothf44f3712014-10-01 14:05:51 -0700102 for (Variable *Var : Vars) {
Jim Stichnothc4554d72014-09-30 16:49:38 -0700103 // Explicitly don't consider zero-weight variables, which are
104 // meant to be spill slots.
105 if (Var->getWeight() == RegWeight::Zero)
106 continue;
107 // Don't bother if the variable has a null live range, which means
108 // it was never referenced.
109 if (Var->getLiveRange().isEmpty())
110 continue;
Jim Stichnoth037fa1d2014-10-07 11:09:33 -0700111 Var->untrimLiveRange();
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700112 Unhandled.push_back(Var);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700113 if (Var->hasReg()) {
114 Var->setRegNumTmp(Var->getRegNum());
115 Var->setLiveRangeInfiniteWeight();
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700116 UnhandledPrecolored.push_back(Var);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700117 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700118 }
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700119 struct CompareRanges {
120 bool operator()(const Variable *L, const Variable *R) {
121 InstNumberT Lstart = L->getLiveRange().getStart();
122 InstNumberT Rstart = R->getLiveRange().getStart();
123 if (Lstart == Rstart)
124 return L->getIndex() < R->getIndex();
125 return Lstart < Rstart;
126 }
127 };
Jim Stichnothe22f8232014-10-13 16:20:59 -0700128 // Do a reverse sort so that erasing elements (from the end) is fast.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700129 std::sort(Unhandled.rbegin(), Unhandled.rend(), CompareRanges());
Jim Stichnothe22f8232014-10-13 16:20:59 -0700130 std::sort(UnhandledPrecolored.rbegin(), UnhandledPrecolored.rend(),
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700131 CompareRanges());
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700132 }
133
134 // RegUses[I] is the number of live ranges (variables) that register
135 // I is currently assigned to. It can be greater than 1 as a result
Jim Stichnothc4554d72014-09-30 16:49:38 -0700136 // of AllowOverlap inference below.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700137 std::vector<int> RegUses(RegMaskFull.size());
138 // Unhandled is already set to all ranges in increasing order of
139 // start points.
140 assert(Active.empty());
141 assert(Inactive.empty());
142 assert(Handled.empty());
143 UnorderedRanges::iterator Next;
144
145 while (!Unhandled.empty()) {
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700146 Variable *Cur = Unhandled.back();
Jim Stichnothe22f8232014-10-13 16:20:59 -0700147 Unhandled.pop_back();
Jim Stichnothc4554d72014-09-30 16:49:38 -0700148 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700149 Str << "\nConsidering ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700150 dumpLiveRange(Cur, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700151 Str << "\n";
152 }
153 const llvm::SmallBitVector RegMask =
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700154 RegMaskFull & Func->getTarget()->getRegisterSetForType(Cur->getType());
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700155
156 // Check for precolored ranges. If Cur is precolored, it
157 // definitely gets that register. Previously processed live
158 // ranges would have avoided that register due to it being
159 // precolored. Future processed live ranges won't evict that
160 // register because the live range has infinite weight.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700161 if (Cur->hasReg()) {
162 int32_t RegNum = Cur->getRegNum();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700163 // RegNumTmp should have already been set above.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700164 assert(Cur->getRegNumTmp() == RegNum);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700165 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700166 Str << "Precoloring ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700167 dumpLiveRange(Cur, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700168 Str << "\n";
169 }
170 Active.push_back(Cur);
171 assert(RegUses[RegNum] >= 0);
172 ++RegUses[RegNum];
Jim Stichnoth541ba662014-10-02 12:58:21 -0700173 assert(!UnhandledPrecolored.empty());
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700174 assert(UnhandledPrecolored.back() == Cur);
Jim Stichnothe22f8232014-10-13 16:20:59 -0700175 UnhandledPrecolored.pop_back();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700176 continue;
177 }
178
179 // Check for active ranges that have expired or become inactive.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700180 for (auto I = Active.begin(), E = Active.end(); I != E; I = Next) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700181 Next = I;
182 ++Next;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700183 Variable *Item = *I;
184 Item->trimLiveRange(Cur->getLiveRange().getStart());
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700185 bool Moved = false;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700186 if (Item->rangeEndsBefore(Cur)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700187 // Move Item from Active to Handled list.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700188 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700189 Str << "Expiring ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700190 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700191 Str << "\n";
192 }
Jim Stichnothe22f8232014-10-13 16:20:59 -0700193 Handled.splice(Handled.end(), Active, I);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700194 Moved = true;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700195 } else if (!Item->rangeOverlapsStart(Cur)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700196 // Move Item from Active to Inactive list.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700197 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700198 Str << "Inactivating ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700199 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700200 Str << "\n";
201 }
Jim Stichnothe22f8232014-10-13 16:20:59 -0700202 Inactive.splice(Inactive.end(), Active, I);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700203 Moved = true;
204 }
205 if (Moved) {
206 // Decrement Item from RegUses[].
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700207 assert(Item->hasRegTmp());
208 int32_t RegNum = Item->getRegNumTmp();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700209 --RegUses[RegNum];
210 assert(RegUses[RegNum] >= 0);
211 }
212 }
213
214 // Check for inactive ranges that have expired or reactivated.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700215 for (auto I = Inactive.begin(), E = Inactive.end(); I != E; I = Next) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700216 Next = I;
217 ++Next;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700218 Variable *Item = *I;
219 Item->trimLiveRange(Cur->getLiveRange().getStart());
Jim Stichnoth037fa1d2014-10-07 11:09:33 -0700220 // As an optimization, don't bother checking pure point-valued
221 // Inactive ranges, because the overlapsStart() test will never
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700222 // succeed, and the rangeEndsBefore() test will generally only
Jim Stichnoth037fa1d2014-10-07 11:09:33 -0700223 // succeed after the last call instruction, which statistically
224 // happens near the end. TODO(stichnot): Consider suppressing
225 // this check every N iterations in case calls are only at the
226 // beginning of the function.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700227 if (!Item->getLiveRange().isNonpoints())
Jim Stichnoth037fa1d2014-10-07 11:09:33 -0700228 continue;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700229 if (Item->rangeEndsBefore(Cur)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700230 // Move Item from Inactive to Handled list.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700231 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700232 Str << "Expiring ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700233 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700234 Str << "\n";
235 }
Jim Stichnothe22f8232014-10-13 16:20:59 -0700236 Handled.splice(Handled.end(), Inactive, I);
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700237 } else if (Item->rangeOverlapsStart(Cur)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700238 // Move Item from Inactive to Active list.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700239 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700240 Str << "Reactivating ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700241 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700242 Str << "\n";
243 }
Jim Stichnothe22f8232014-10-13 16:20:59 -0700244 Active.splice(Active.end(), Inactive, I);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700245 // Increment Item in RegUses[].
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700246 assert(Item->hasRegTmp());
247 int32_t RegNum = Item->getRegNumTmp();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700248 assert(RegUses[RegNum] >= 0);
249 ++RegUses[RegNum];
250 }
251 }
252
253 // Calculate available registers into Free[].
254 llvm::SmallBitVector Free = RegMask;
255 for (SizeT i = 0; i < RegMask.size(); ++i) {
256 if (RegUses[i] > 0)
257 Free[i] = false;
258 }
259
Jim Stichnothad403532014-09-25 12:44:17 -0700260 // Infer register preference and allowable overlap. Only form a
261 // preference when the current Variable has an unambiguous "first"
262 // definition. The preference is some source Variable of the
263 // defining instruction that either is assigned a register that is
264 // currently free, or that is assigned a register that is not free
265 // but overlap is allowed. Overlap is allowed when the Variable
266 // under consideration is single-definition, and its definition is
267 // a simple assignment - i.e., the register gets copied/aliased
268 // but is never modified. Furthermore, overlap is only allowed
269 // when preferred Variable definition instructions do not appear
270 // within the current Variable's live range.
271 Variable *Prefer = NULL;
272 int32_t PreferReg = Variable::NoRegister;
273 bool AllowOverlap = false;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700274 if (const Inst *DefInst = VMetadata->getFirstDefinition(Cur)) {
275 assert(DefInst->getDest() == Cur);
Jim Stichnothad403532014-09-25 12:44:17 -0700276 bool IsAssign = DefInst->isSimpleAssign();
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700277 bool IsSingleDef = !VMetadata->isMultiDef(Cur);
Jim Stichnothad403532014-09-25 12:44:17 -0700278 for (SizeT i = 0; i < DefInst->getSrcSize(); ++i) {
279 // TODO(stichnot): Iterate through the actual Variables of the
280 // instruction, not just the source operands. This could
281 // capture Load instructions, including address mode
282 // optimization, for Prefer (but not for AllowOverlap).
283 if (Variable *SrcVar = llvm::dyn_cast<Variable>(DefInst->getSrc(i))) {
284 int32_t SrcReg = SrcVar->getRegNumTmp();
285 // Only consider source variables that have (so far) been
286 // assigned a register. That register must be one in the
287 // RegMask set, e.g. don't try to prefer the stack pointer
288 // as a result of the stacksave intrinsic.
289 if (SrcVar->hasRegTmp() && RegMask[SrcReg]) {
290 if (!Free[SrcReg]) {
291 // Don't bother trying to enable AllowOverlap if the
292 // register is already free.
293 AllowOverlap =
294 IsSingleDef && IsAssign && !overlapsDefs(Func, Cur, SrcVar);
295 }
296 if (AllowOverlap || Free[SrcReg]) {
297 Prefer = SrcVar;
298 PreferReg = SrcReg;
299 }
300 }
301 }
302 }
303 }
Jim Stichnothc4554d72014-09-30 16:49:38 -0700304 if (Verbose) {
Jim Stichnothad403532014-09-25 12:44:17 -0700305 if (Prefer) {
306 Str << "Initial Prefer=" << *Prefer << " R=" << PreferReg
307 << " LIVE=" << Prefer->getLiveRange() << " Overlap=" << AllowOverlap
308 << "\n";
309 }
310 }
311
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700312 // Remove registers from the Free[] list where an Inactive range
313 // overlaps with the current range.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700314 for (const Variable *Item : Inactive) {
315 if (Item->rangeOverlaps(Cur)) {
316 int32_t RegNum = Item->getRegNumTmp();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700317 // Don't assert(Free[RegNum]) because in theory (though
318 // probably never in practice) there could be two inactive
Jim Stichnothc4554d72014-09-30 16:49:38 -0700319 // variables that were marked with AllowOverlap.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700320 Free[RegNum] = false;
Jim Stichnothad403532014-09-25 12:44:17 -0700321 // Disable AllowOverlap if an Inactive variable, which is not
322 // Prefer, shares Prefer's register, and has a definition
323 // within Cur's live range.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700324 if (AllowOverlap && Item != Prefer && RegNum == PreferReg &&
325 overlapsDefs(Func, Cur, Item)) {
Jim Stichnothad403532014-09-25 12:44:17 -0700326 AllowOverlap = false;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700327 dumpDisableOverlap(Func, Item, "Inactive");
Jim Stichnothad403532014-09-25 12:44:17 -0700328 }
329 }
330 }
331
332 // Disable AllowOverlap if an Active variable, which is not
333 // Prefer, shares Prefer's register, and has a definition within
334 // Cur's live range.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700335 for (const Variable *Item : Active) {
336 int32_t RegNum = Item->getRegNumTmp();
337 if (Item != Prefer && RegNum == PreferReg &&
338 overlapsDefs(Func, Cur, Item)) {
Jim Stichnothad403532014-09-25 12:44:17 -0700339 AllowOverlap = false;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700340 dumpDisableOverlap(Func, Item, "Active");
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700341 }
342 }
343
Jim Stichnoth541ba662014-10-02 12:58:21 -0700344 std::vector<RegWeight> Weights(RegMask.size());
345
346 // Remove registers from the Free[] list where an Unhandled
347 // precolored range overlaps with the current range, and set those
348 // registers to infinite weight so that they aren't candidates for
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700349 // eviction. Cur->rangeEndsBefore(Item) is an early exit check
350 // that turns a guaranteed O(N^2) algorithm into expected linear
Jim Stichnoth541ba662014-10-02 12:58:21 -0700351 // complexity.
352 llvm::SmallBitVector PrecoloredUnhandledMask(RegMask.size());
353 // Note: PrecoloredUnhandledMask is only used for dumping.
Jim Stichnothe22f8232014-10-13 16:20:59 -0700354 for (auto I = UnhandledPrecolored.rbegin(), E = UnhandledPrecolored.rend();
355 I != E; ++I) {
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700356 Variable *Item = *I;
357 assert(Item->hasReg());
358 if (Cur->rangeEndsBefore(Item))
Jim Stichnothf44f3712014-10-01 14:05:51 -0700359 break;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700360 if (Item->rangeOverlaps(Cur)) {
361 int32_t ItemReg = Item->getRegNum(); // Note: not getRegNumTmp()
Jim Stichnoth541ba662014-10-02 12:58:21 -0700362 Weights[ItemReg].setWeight(RegWeight::Inf);
Jim Stichnothad403532014-09-25 12:44:17 -0700363 Free[ItemReg] = false;
Jim Stichnoth541ba662014-10-02 12:58:21 -0700364 PrecoloredUnhandledMask[ItemReg] = true;
Jim Stichnothad403532014-09-25 12:44:17 -0700365 // Disable AllowOverlap if the preferred register is one of
366 // these precolored unhandled overlapping ranges.
367 if (AllowOverlap && ItemReg == PreferReg) {
368 AllowOverlap = false;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700369 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled");
Jim Stichnothad403532014-09-25 12:44:17 -0700370 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700371 }
372 }
373
374 // Print info about physical register availability.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700375 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700376 for (SizeT i = 0; i < RegMask.size(); ++i) {
377 if (RegMask[i]) {
378 Str << Func->getTarget()->getRegName(i, IceType_i32)
Jim Stichnothca662e92014-07-10 15:32:36 -0700379 << "(U=" << RegUses[i] << ",F=" << Free[i]
Jim Stichnoth541ba662014-10-02 12:58:21 -0700380 << ",P=" << PrecoloredUnhandledMask[i] << ") ";
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700381 }
382 }
383 Str << "\n";
384 }
385
Jim Stichnothad403532014-09-25 12:44:17 -0700386 if (Prefer && (AllowOverlap || Free[PreferReg])) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700387 // First choice: a preferred register that is either free or is
388 // allowed to overlap with its linked variable.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700389 Cur->setRegNumTmp(PreferReg);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700390 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700391 Str << "Preferring ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700392 dumpLiveRange(Cur, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700393 Str << "\n";
394 }
395 assert(RegUses[PreferReg] >= 0);
396 ++RegUses[PreferReg];
397 Active.push_back(Cur);
398 } else if (Free.any()) {
399 // Second choice: any free register. TODO: After explicit
400 // affinity is considered, is there a strategy better than just
401 // picking the lowest-numbered available register?
402 int32_t RegNum = Free.find_first();
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700403 Cur->setRegNumTmp(RegNum);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700404 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700405 Str << "Allocating ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700406 dumpLiveRange(Cur, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700407 Str << "\n";
408 }
409 assert(RegUses[RegNum] >= 0);
410 ++RegUses[RegNum];
411 Active.push_back(Cur);
412 } else {
413 // Fallback: there are no free registers, so we look for the
414 // lowest-weight register and see if Cur has higher weight.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700415 // Check Active ranges.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700416 for (const Variable *Item : Active) {
417 assert(Item->rangeOverlaps(Cur));
418 int32_t RegNum = Item->getRegNumTmp();
419 assert(Item->hasRegTmp());
420 Weights[RegNum].addWeight(Item->getLiveRange().getWeight());
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700421 }
422 // Same as above, but check Inactive ranges instead of Active.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700423 for (const Variable *Item : Inactive) {
424 int32_t RegNum = Item->getRegNumTmp();
425 assert(Item->hasRegTmp());
426 if (Item->rangeOverlaps(Cur))
427 Weights[RegNum].addWeight(Item->getLiveRange().getWeight());
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700428 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700429
430 // All the weights are now calculated. Find the register with
431 // smallest weight.
432 int32_t MinWeightIndex = RegMask.find_first();
433 // MinWeightIndex must be valid because of the initial
434 // RegMask.any() test.
435 assert(MinWeightIndex >= 0);
436 for (SizeT i = MinWeightIndex + 1; i < Weights.size(); ++i) {
437 if (RegMask[i] && Weights[i] < Weights[MinWeightIndex])
438 MinWeightIndex = i;
439 }
440
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700441 if (Cur->getLiveRange().getWeight() <= Weights[MinWeightIndex]) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700442 // Cur doesn't have priority over any other live ranges, so
443 // don't allocate any register to it, and move it to the
444 // Handled state.
445 Handled.push_back(Cur);
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700446 if (Cur->getLiveRange().getWeight().isInf()) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700447 Func->setError("Unable to find a physical register for an "
448 "infinite-weight live range");
449 }
450 } else {
451 // Evict all live ranges in Active that register number
452 // MinWeightIndex is assigned to.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700453 for (auto I = Active.begin(), E = Active.end(); I != E; I = Next) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700454 Next = I;
455 ++Next;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700456 Variable *Item = *I;
457 if (Item->getRegNumTmp() == MinWeightIndex) {
Jim Stichnothc4554d72014-09-30 16:49:38 -0700458 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700459 Str << "Evicting ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700460 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700461 Str << "\n";
462 }
463 --RegUses[MinWeightIndex];
464 assert(RegUses[MinWeightIndex] >= 0);
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700465 Item->setRegNumTmp(Variable::NoRegister);
Jim Stichnothe22f8232014-10-13 16:20:59 -0700466 Handled.splice(Handled.end(), Active, I);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700467 }
468 }
469 // Do the same for Inactive.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700470 for (auto I = Inactive.begin(), E = Inactive.end(); I != E; I = Next) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700471 Next = I;
472 ++Next;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700473 Variable *Item = *I;
474 // Note: The Item->rangeOverlaps(Cur) clause is not part of the
Jim Stichnoth68e28192014-07-24 08:48:15 -0700475 // description of AssignMemLoc() in the original paper. But
476 // there doesn't seem to be any need to evict an inactive
477 // live range that doesn't overlap with the live range
478 // currently being considered. It's especially bad if we
479 // would end up evicting an infinite-weight but
480 // currently-inactive live range. The most common situation
481 // for this would be a scratch register kill set for call
482 // instructions.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700483 if (Item->getRegNumTmp() == MinWeightIndex &&
484 Item->rangeOverlaps(Cur)) {
Jim Stichnothc4554d72014-09-30 16:49:38 -0700485 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700486 Str << "Evicting ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700487 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700488 Str << "\n";
489 }
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700490 Item->setRegNumTmp(Variable::NoRegister);
Jim Stichnothe22f8232014-10-13 16:20:59 -0700491 Handled.splice(Handled.end(), Inactive, I);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700492 }
493 }
494 // Assign the register to Cur.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700495 Cur->setRegNumTmp(MinWeightIndex);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700496 assert(RegUses[MinWeightIndex] >= 0);
497 ++RegUses[MinWeightIndex];
498 Active.push_back(Cur);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700499 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700500 Str << "Allocating ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700501 dumpLiveRange(Cur, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700502 Str << "\n";
503 }
504 }
505 }
506 dump(Func);
507 }
508 // Move anything Active or Inactive to Handled for easier handling.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700509 for (Variable *I : Active)
Jim Stichnothf44f3712014-10-01 14:05:51 -0700510 Handled.push_back(I);
511 Active.clear();
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700512 for (Variable *I : Inactive)
Jim Stichnothf44f3712014-10-01 14:05:51 -0700513 Handled.push_back(I);
514 Inactive.clear();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700515 dump(Func);
516
517 // Finish up by assigning RegNumTmp->RegNum for each Variable.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700518 for (Variable *Item : Handled) {
519 int32_t RegNum = Item->getRegNumTmp();
Jim Stichnothc4554d72014-09-30 16:49:38 -0700520 if (Verbose) {
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700521 if (!Item->hasRegTmp()) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700522 Str << "Not assigning ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700523 Item->dump(Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700524 Str << "\n";
525 } else {
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700526 Str << (RegNum == Item->getRegNum() ? "Reassigning " : "Assigning ")
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700527 << Func->getTarget()->getRegName(RegNum, IceType_i32) << "(r"
528 << RegNum << ") to ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700529 Item->dump(Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700530 Str << "\n";
531 }
532 }
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700533 Item->setRegNum(Item->getRegNumTmp());
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700534 }
535
536 // TODO: Consider running register allocation one more time, with
537 // infinite registers, for two reasons. First, evicted live ranges
538 // get a second chance for a register. Second, it allows coalescing
539 // of stack slots. If there is no time budget for the second
540 // register allocation run, each unallocated variable just gets its
541 // own slot.
542 //
543 // Another idea for coalescing stack slots is to initialize the
544 // Unhandled list with just the unallocated variables, saving time
545 // but not offering second-chance opportunities.
546}
547
548// ======================== Dump routines ======================== //
549
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700550void LinearScan::dump(Cfg *Func) const {
551 Ostream &Str = Func->getContext()->getStrDump();
552 if (!Func->getContext()->isVerbose(IceV_LinearScan))
553 return;
Jim Stichnoth800dab22014-09-20 12:25:02 -0700554 Func->resetCurrentNode();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700555 Str << "**** Current regalloc state:\n";
556 Str << "++++++ Handled:\n";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700557 for (const Variable *Item : Handled) {
558 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700559 Str << "\n";
560 }
561 Str << "++++++ Unhandled:\n";
Jim Stichnothe22f8232014-10-13 16:20:59 -0700562 for (auto I = Unhandled.rbegin(), E = Unhandled.rend(); I != E; ++I) {
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700563 dumpLiveRange(*I, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700564 Str << "\n";
565 }
566 Str << "++++++ Active:\n";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700567 for (const Variable *Item : Active) {
568 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700569 Str << "\n";
570 }
571 Str << "++++++ Inactive:\n";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700572 for (const Variable *Item : Inactive) {
573 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700574 Str << "\n";
575 }
576}
577
578} // end of namespace Ice