blob: 69353a1df9bb20ff8dd3ee86cd8ed9b6f5ccc1db [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.
27bool overlapsDefs(const Cfg *Func, const LiveRangeWrapper &Item,
28 const Variable *Var) {
29 const InstDefList &Defs = Func->getVMetadata()->getDefinitions(Var);
30 for (size_t i = 0; i < Defs.size(); ++i) {
31 if (Item.range().overlaps(Defs[i]->getNumber()))
32 return true;
33 }
34 return false;
35}
36
37void dumpDisableOverlap(const Cfg *Func, const Variable *Var,
38 const char *Reason) {
39 if (Func->getContext()->isVerbose(IceV_LinearScan)) {
40 Ostream &Str = Func->getContext()->getStrDump();
41 Str << "Disabling Overlap due to " << Reason << " " << *Var
42 << " LIVE=" << Var->getLiveRange() << " Defs=";
43 const InstDefList &Defs = Func->getVMetadata()->getDefinitions(Var);
44 for (size_t i = 0; i < Defs.size(); ++i) {
45 if (i > 0)
46 Str << ",";
47 Str << Defs[i]->getNumber();
48 }
49 Str << "\n";
50 }
51}
52
53} // end of anonymous namespace
54
Jim Stichnothd97c7df2014-06-04 11:57:08 -070055// Implements the linear-scan algorithm. Based on "Linear Scan
56// Register Allocation in the Context of SSA Form and Register
57// Constraints" by Hanspeter Mössenböck and Michael Pfeiffer,
58// ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF . This
59// implementation is modified to take affinity into account and allow
60// two interfering variables to share the same register in certain
61// cases.
62//
Jim Stichnoth800dab22014-09-20 12:25:02 -070063// Requires running Cfg::liveness(Liveness_Intervals) in
Jim Stichnothd97c7df2014-06-04 11:57:08 -070064// preparation. Results are assigned to Variable::RegNum for each
65// Variable.
66void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) {
Jim Stichnothc4554d72014-09-30 16:49:38 -070067 static TimerIdT IDscan = GlobalContext::getTimerID("linearScan");
68 TimerMarker T(IDscan, Func->getContext());
Jim Stichnothd97c7df2014-06-04 11:57:08 -070069 assert(RegMaskFull.any()); // Sanity check
70 Unhandled.clear();
Jim Stichnoth541ba662014-10-02 12:58:21 -070071 UnhandledPrecolored.clear();
Jim Stichnothd97c7df2014-06-04 11:57:08 -070072 Handled.clear();
73 Inactive.clear();
74 Active.clear();
75 Ostream &Str = Func->getContext()->getStrDump();
Jim Stichnothc4554d72014-09-30 16:49:38 -070076 bool Verbose = Func->getContext()->isVerbose(IceV_LinearScan);
Jim Stichnoth800dab22014-09-20 12:25:02 -070077 Func->resetCurrentNode();
Jim Stichnothad403532014-09-25 12:44:17 -070078 VariablesMetadata *VMetadata = Func->getVMetadata();
Jim Stichnothd97c7df2014-06-04 11:57:08 -070079
80 // Gather the live ranges of all variables and add them to the
81 // Unhandled set. TODO: Unhandled is a set<> which is based on a
82 // balanced binary tree, so inserting live ranges for N variables is
83 // O(N log N) complexity. N may be proportional to the number of
84 // instructions, thanks to temporary generation during lowering. As
85 // a result, it may be useful to design a better data structure for
86 // storing Func->getVariables().
87 const VarList &Vars = Func->getVariables();
Jim Stichnothc4554d72014-09-30 16:49:38 -070088 {
89 static TimerIdT IDinitUnhandled =
90 GlobalContext::getTimerID("initUnhandled");
91 TimerMarker T(IDinitUnhandled, Func->getContext());
Jim Stichnothf44f3712014-10-01 14:05:51 -070092 for (Variable *Var : Vars) {
Jim Stichnothc4554d72014-09-30 16:49:38 -070093 // Explicitly don't consider zero-weight variables, which are
94 // meant to be spill slots.
95 if (Var->getWeight() == RegWeight::Zero)
96 continue;
97 // Don't bother if the variable has a null live range, which means
98 // it was never referenced.
99 if (Var->getLiveRange().isEmpty())
100 continue;
Jim Stichnoth541ba662014-10-02 12:58:21 -0700101 LiveRangeWrapper R(Var);
102 Unhandled.insert(R);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700103 if (Var->hasReg()) {
104 Var->setRegNumTmp(Var->getRegNum());
105 Var->setLiveRangeInfiniteWeight();
Jim Stichnoth541ba662014-10-02 12:58:21 -0700106 UnhandledPrecolored.insert(R);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700107 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700108 }
109 }
110
111 // RegUses[I] is the number of live ranges (variables) that register
112 // I is currently assigned to. It can be greater than 1 as a result
Jim Stichnothc4554d72014-09-30 16:49:38 -0700113 // of AllowOverlap inference below.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700114 std::vector<int> RegUses(RegMaskFull.size());
115 // Unhandled is already set to all ranges in increasing order of
116 // start points.
117 assert(Active.empty());
118 assert(Inactive.empty());
119 assert(Handled.empty());
120 UnorderedRanges::iterator Next;
121
122 while (!Unhandled.empty()) {
123 LiveRangeWrapper Cur = *Unhandled.begin();
124 Unhandled.erase(Unhandled.begin());
Jim Stichnothc4554d72014-09-30 16:49:38 -0700125 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700126 Str << "\nConsidering ";
127 Cur.dump(Func);
128 Str << "\n";
129 }
130 const llvm::SmallBitVector RegMask =
131 RegMaskFull &
132 Func->getTarget()->getRegisterSetForType(Cur.Var->getType());
133
134 // Check for precolored ranges. If Cur is precolored, it
135 // definitely gets that register. Previously processed live
136 // ranges would have avoided that register due to it being
137 // precolored. Future processed live ranges won't evict that
138 // register because the live range has infinite weight.
139 if (Cur.Var->hasReg()) {
140 int32_t RegNum = Cur.Var->getRegNum();
141 // RegNumTmp should have already been set above.
142 assert(Cur.Var->getRegNumTmp() == RegNum);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700143 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700144 Str << "Precoloring ";
145 Cur.dump(Func);
146 Str << "\n";
147 }
148 Active.push_back(Cur);
149 assert(RegUses[RegNum] >= 0);
150 ++RegUses[RegNum];
Jim Stichnoth541ba662014-10-02 12:58:21 -0700151 assert(!UnhandledPrecolored.empty());
152 assert(UnhandledPrecolored.begin()->Var == Cur.Var);
153 UnhandledPrecolored.erase(UnhandledPrecolored.begin());
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700154 continue;
155 }
156
157 // Check for active ranges that have expired or become inactive.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700158 for (auto I = Active.begin(), E = Active.end(); I != E; I = Next) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700159 Next = I;
160 ++Next;
161 LiveRangeWrapper Item = *I;
162 bool Moved = false;
163 if (Item.endsBefore(Cur)) {
164 // Move Item from Active to Handled list.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700165 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700166 Str << "Expiring ";
167 Item.dump(Func);
168 Str << "\n";
169 }
170 Active.erase(I);
171 Handled.push_back(Item);
172 Moved = true;
173 } else if (!Item.overlapsStart(Cur)) {
174 // Move Item from Active to Inactive list.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700175 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700176 Str << "Inactivating ";
177 Item.dump(Func);
178 Str << "\n";
179 }
180 Active.erase(I);
181 Inactive.push_back(Item);
182 Moved = true;
183 }
184 if (Moved) {
185 // Decrement Item from RegUses[].
186 assert(Item.Var->hasRegTmp());
187 int32_t RegNum = Item.Var->getRegNumTmp();
188 --RegUses[RegNum];
189 assert(RegUses[RegNum] >= 0);
190 }
191 }
192
193 // Check for inactive ranges that have expired or reactivated.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700194 for (auto I = Inactive.begin(), E = Inactive.end(); I != E; I = Next) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700195 Next = I;
196 ++Next;
197 LiveRangeWrapper Item = *I;
198 if (Item.endsBefore(Cur)) {
199 // Move Item from Inactive to Handled list.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700200 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700201 Str << "Expiring ";
202 Item.dump(Func);
203 Str << "\n";
204 }
205 Inactive.erase(I);
206 Handled.push_back(Item);
207 } else if (Item.overlapsStart(Cur)) {
208 // Move Item from Inactive to Active list.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700209 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700210 Str << "Reactivating ";
211 Item.dump(Func);
212 Str << "\n";
213 }
214 Inactive.erase(I);
215 Active.push_back(Item);
216 // Increment Item in RegUses[].
217 assert(Item.Var->hasRegTmp());
218 int32_t RegNum = Item.Var->getRegNumTmp();
219 assert(RegUses[RegNum] >= 0);
220 ++RegUses[RegNum];
221 }
222 }
223
224 // Calculate available registers into Free[].
225 llvm::SmallBitVector Free = RegMask;
226 for (SizeT i = 0; i < RegMask.size(); ++i) {
227 if (RegUses[i] > 0)
228 Free[i] = false;
229 }
230
Jim Stichnothad403532014-09-25 12:44:17 -0700231 // Infer register preference and allowable overlap. Only form a
232 // preference when the current Variable has an unambiguous "first"
233 // definition. The preference is some source Variable of the
234 // defining instruction that either is assigned a register that is
235 // currently free, or that is assigned a register that is not free
236 // but overlap is allowed. Overlap is allowed when the Variable
237 // under consideration is single-definition, and its definition is
238 // a simple assignment - i.e., the register gets copied/aliased
239 // but is never modified. Furthermore, overlap is only allowed
240 // when preferred Variable definition instructions do not appear
241 // within the current Variable's live range.
242 Variable *Prefer = NULL;
243 int32_t PreferReg = Variable::NoRegister;
244 bool AllowOverlap = false;
245 if (const Inst *DefInst = VMetadata->getFirstDefinition(Cur.Var)) {
246 assert(DefInst->getDest() == Cur.Var);
247 bool IsAssign = DefInst->isSimpleAssign();
248 bool IsSingleDef = !VMetadata->isMultiDef(Cur.Var);
249 for (SizeT i = 0; i < DefInst->getSrcSize(); ++i) {
250 // TODO(stichnot): Iterate through the actual Variables of the
251 // instruction, not just the source operands. This could
252 // capture Load instructions, including address mode
253 // optimization, for Prefer (but not for AllowOverlap).
254 if (Variable *SrcVar = llvm::dyn_cast<Variable>(DefInst->getSrc(i))) {
255 int32_t SrcReg = SrcVar->getRegNumTmp();
256 // Only consider source variables that have (so far) been
257 // assigned a register. That register must be one in the
258 // RegMask set, e.g. don't try to prefer the stack pointer
259 // as a result of the stacksave intrinsic.
260 if (SrcVar->hasRegTmp() && RegMask[SrcReg]) {
261 if (!Free[SrcReg]) {
262 // Don't bother trying to enable AllowOverlap if the
263 // register is already free.
264 AllowOverlap =
265 IsSingleDef && IsAssign && !overlapsDefs(Func, Cur, SrcVar);
266 }
267 if (AllowOverlap || Free[SrcReg]) {
268 Prefer = SrcVar;
269 PreferReg = SrcReg;
270 }
271 }
272 }
273 }
274 }
Jim Stichnothc4554d72014-09-30 16:49:38 -0700275 if (Verbose) {
Jim Stichnothad403532014-09-25 12:44:17 -0700276 if (Prefer) {
277 Str << "Initial Prefer=" << *Prefer << " R=" << PreferReg
278 << " LIVE=" << Prefer->getLiveRange() << " Overlap=" << AllowOverlap
279 << "\n";
280 }
281 }
282
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700283 // Remove registers from the Free[] list where an Inactive range
284 // overlaps with the current range.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700285 for (const LiveRangeWrapper &Item : Inactive) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700286 if (Item.overlaps(Cur)) {
287 int32_t RegNum = Item.Var->getRegNumTmp();
288 // Don't assert(Free[RegNum]) because in theory (though
289 // probably never in practice) there could be two inactive
Jim Stichnothc4554d72014-09-30 16:49:38 -0700290 // variables that were marked with AllowOverlap.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700291 Free[RegNum] = false;
Jim Stichnothad403532014-09-25 12:44:17 -0700292 // Disable AllowOverlap if an Inactive variable, which is not
293 // Prefer, shares Prefer's register, and has a definition
294 // within Cur's live range.
295 if (AllowOverlap && Item.Var != Prefer && RegNum == PreferReg &&
296 overlapsDefs(Func, Cur, Item.Var)) {
297 AllowOverlap = false;
298 dumpDisableOverlap(Func, Item.Var, "Inactive");
299 }
300 }
301 }
302
303 // Disable AllowOverlap if an Active variable, which is not
304 // Prefer, shares Prefer's register, and has a definition within
305 // Cur's live range.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700306 for (const LiveRangeWrapper &Item : Active) {
Jim Stichnothad403532014-09-25 12:44:17 -0700307 int32_t RegNum = Item.Var->getRegNumTmp();
308 if (Item.Var != Prefer && RegNum == PreferReg &&
309 overlapsDefs(Func, Cur, Item.Var)) {
310 AllowOverlap = false;
311 dumpDisableOverlap(Func, Item.Var, "Active");
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700312 }
313 }
314
Jim Stichnoth541ba662014-10-02 12:58:21 -0700315 std::vector<RegWeight> Weights(RegMask.size());
316
317 // Remove registers from the Free[] list where an Unhandled
318 // precolored range overlaps with the current range, and set those
319 // registers to infinite weight so that they aren't candidates for
320 // eviction. Cur.endsBefore(Item) is an early exit check that
321 // turns a guaranteed O(N^2) algorithm into expected linear
322 // complexity.
323 llvm::SmallBitVector PrecoloredUnhandledMask(RegMask.size());
324 // Note: PrecoloredUnhandledMask is only used for dumping.
325 for (const LiveRangeWrapper &Item : UnhandledPrecolored) {
326 assert(Item.Var->hasReg());
Jim Stichnothf44f3712014-10-01 14:05:51 -0700327 if (Cur.endsBefore(Item))
328 break;
Jim Stichnoth541ba662014-10-02 12:58:21 -0700329 if (Item.overlaps(Cur)) {
Jim Stichnothad403532014-09-25 12:44:17 -0700330 int32_t ItemReg = Item.Var->getRegNum(); // Note: not getRegNumTmp()
Jim Stichnoth541ba662014-10-02 12:58:21 -0700331 Weights[ItemReg].setWeight(RegWeight::Inf);
Jim Stichnothad403532014-09-25 12:44:17 -0700332 Free[ItemReg] = false;
Jim Stichnoth541ba662014-10-02 12:58:21 -0700333 PrecoloredUnhandledMask[ItemReg] = true;
Jim Stichnothad403532014-09-25 12:44:17 -0700334 // Disable AllowOverlap if the preferred register is one of
335 // these precolored unhandled overlapping ranges.
336 if (AllowOverlap && ItemReg == PreferReg) {
337 AllowOverlap = false;
338 dumpDisableOverlap(Func, Item.Var, "PrecoloredUnhandled");
339 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700340 }
341 }
342
343 // Print info about physical register availability.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700344 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700345 for (SizeT i = 0; i < RegMask.size(); ++i) {
346 if (RegMask[i]) {
347 Str << Func->getTarget()->getRegName(i, IceType_i32)
Jim Stichnothca662e92014-07-10 15:32:36 -0700348 << "(U=" << RegUses[i] << ",F=" << Free[i]
Jim Stichnoth541ba662014-10-02 12:58:21 -0700349 << ",P=" << PrecoloredUnhandledMask[i] << ") ";
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700350 }
351 }
352 Str << "\n";
353 }
354
Jim Stichnothad403532014-09-25 12:44:17 -0700355 if (Prefer && (AllowOverlap || Free[PreferReg])) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700356 // First choice: a preferred register that is either free or is
357 // allowed to overlap with its linked variable.
358 Cur.Var->setRegNumTmp(PreferReg);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700359 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700360 Str << "Preferring ";
361 Cur.dump(Func);
362 Str << "\n";
363 }
364 assert(RegUses[PreferReg] >= 0);
365 ++RegUses[PreferReg];
366 Active.push_back(Cur);
367 } else if (Free.any()) {
368 // Second choice: any free register. TODO: After explicit
369 // affinity is considered, is there a strategy better than just
370 // picking the lowest-numbered available register?
371 int32_t RegNum = Free.find_first();
372 Cur.Var->setRegNumTmp(RegNum);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700373 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700374 Str << "Allocating ";
375 Cur.dump(Func);
376 Str << "\n";
377 }
378 assert(RegUses[RegNum] >= 0);
379 ++RegUses[RegNum];
380 Active.push_back(Cur);
381 } else {
382 // Fallback: there are no free registers, so we look for the
383 // lowest-weight register and see if Cur has higher weight.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700384 // Check Active ranges.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700385 for (const LiveRangeWrapper &Item : Active) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700386 assert(Item.overlaps(Cur));
387 int32_t RegNum = Item.Var->getRegNumTmp();
388 assert(Item.Var->hasRegTmp());
389 Weights[RegNum].addWeight(Item.range().getWeight());
390 }
391 // Same as above, but check Inactive ranges instead of Active.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700392 for (const LiveRangeWrapper &Item : Inactive) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700393 int32_t RegNum = Item.Var->getRegNumTmp();
394 assert(Item.Var->hasRegTmp());
395 if (Item.overlaps(Cur))
396 Weights[RegNum].addWeight(Item.range().getWeight());
397 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700398
399 // All the weights are now calculated. Find the register with
400 // smallest weight.
401 int32_t MinWeightIndex = RegMask.find_first();
402 // MinWeightIndex must be valid because of the initial
403 // RegMask.any() test.
404 assert(MinWeightIndex >= 0);
405 for (SizeT i = MinWeightIndex + 1; i < Weights.size(); ++i) {
406 if (RegMask[i] && Weights[i] < Weights[MinWeightIndex])
407 MinWeightIndex = i;
408 }
409
410 if (Cur.range().getWeight() <= Weights[MinWeightIndex]) {
411 // Cur doesn't have priority over any other live ranges, so
412 // don't allocate any register to it, and move it to the
413 // Handled state.
414 Handled.push_back(Cur);
415 if (Cur.range().getWeight().isInf()) {
416 Func->setError("Unable to find a physical register for an "
417 "infinite-weight live range");
418 }
419 } else {
420 // Evict all live ranges in Active that register number
421 // MinWeightIndex is assigned to.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700422 for (auto I = Active.begin(), E = Active.end(); I != E; I = Next) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700423 Next = I;
424 ++Next;
425 LiveRangeWrapper Item = *I;
426 if (Item.Var->getRegNumTmp() == MinWeightIndex) {
Jim Stichnothc4554d72014-09-30 16:49:38 -0700427 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700428 Str << "Evicting ";
429 Item.dump(Func);
430 Str << "\n";
431 }
432 --RegUses[MinWeightIndex];
433 assert(RegUses[MinWeightIndex] >= 0);
434 Item.Var->setRegNumTmp(Variable::NoRegister);
435 Active.erase(I);
436 Handled.push_back(Item);
437 }
438 }
439 // Do the same for Inactive.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700440 for (auto I = Inactive.begin(), E = Inactive.end(); I != E; I = Next) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700441 Next = I;
442 ++Next;
443 LiveRangeWrapper Item = *I;
Jim Stichnoth68e28192014-07-24 08:48:15 -0700444 // Note: The Item.overlaps(Cur) clause is not part of the
445 // description of AssignMemLoc() in the original paper. But
446 // there doesn't seem to be any need to evict an inactive
447 // live range that doesn't overlap with the live range
448 // currently being considered. It's especially bad if we
449 // would end up evicting an infinite-weight but
450 // currently-inactive live range. The most common situation
451 // for this would be a scratch register kill set for call
452 // instructions.
453 if (Item.Var->getRegNumTmp() == MinWeightIndex &&
454 Item.overlaps(Cur)) {
Jim Stichnothc4554d72014-09-30 16:49:38 -0700455 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700456 Str << "Evicting ";
457 Item.dump(Func);
458 Str << "\n";
459 }
460 Item.Var->setRegNumTmp(Variable::NoRegister);
461 Inactive.erase(I);
462 Handled.push_back(Item);
463 }
464 }
465 // Assign the register to Cur.
466 Cur.Var->setRegNumTmp(MinWeightIndex);
467 assert(RegUses[MinWeightIndex] >= 0);
468 ++RegUses[MinWeightIndex];
469 Active.push_back(Cur);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700470 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700471 Str << "Allocating ";
472 Cur.dump(Func);
473 Str << "\n";
474 }
475 }
476 }
477 dump(Func);
478 }
479 // Move anything Active or Inactive to Handled for easier handling.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700480 for (const LiveRangeWrapper &I : Active)
481 Handled.push_back(I);
482 Active.clear();
483 for (const LiveRangeWrapper &I : Inactive)
484 Handled.push_back(I);
485 Inactive.clear();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700486 dump(Func);
487
488 // Finish up by assigning RegNumTmp->RegNum for each Variable.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700489 for (const LiveRangeWrapper &Item : Handled) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700490 int32_t RegNum = Item.Var->getRegNumTmp();
Jim Stichnothc4554d72014-09-30 16:49:38 -0700491 if (Verbose) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700492 if (!Item.Var->hasRegTmp()) {
493 Str << "Not assigning ";
494 Item.Var->dump(Func);
495 Str << "\n";
496 } else {
497 Str << (RegNum == Item.Var->getRegNum() ? "Reassigning " : "Assigning ")
498 << Func->getTarget()->getRegName(RegNum, IceType_i32) << "(r"
499 << RegNum << ") to ";
500 Item.Var->dump(Func);
501 Str << "\n";
502 }
503 }
504 Item.Var->setRegNum(Item.Var->getRegNumTmp());
505 }
506
507 // TODO: Consider running register allocation one more time, with
508 // infinite registers, for two reasons. First, evicted live ranges
509 // get a second chance for a register. Second, it allows coalescing
510 // of stack slots. If there is no time budget for the second
511 // register allocation run, each unallocated variable just gets its
512 // own slot.
513 //
514 // Another idea for coalescing stack slots is to initialize the
515 // Unhandled list with just the unallocated variables, saving time
516 // but not offering second-chance opportunities.
517}
518
519// ======================== Dump routines ======================== //
520
521void LiveRangeWrapper::dump(const Cfg *Func) const {
522 Ostream &Str = Func->getContext()->getStrDump();
523 const static size_t BufLen = 30;
524 char buf[BufLen];
525 snprintf(buf, BufLen, "%2d", Var->getRegNumTmp());
526 Str << "R=" << buf << " V=";
527 Var->dump(Func);
528 Str << " Range=" << range();
529}
530
531void LinearScan::dump(Cfg *Func) const {
532 Ostream &Str = Func->getContext()->getStrDump();
533 if (!Func->getContext()->isVerbose(IceV_LinearScan))
534 return;
Jim Stichnoth800dab22014-09-20 12:25:02 -0700535 Func->resetCurrentNode();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700536 Str << "**** Current regalloc state:\n";
537 Str << "++++++ Handled:\n";
Jim Stichnothf44f3712014-10-01 14:05:51 -0700538 for (const LiveRangeWrapper &Item : Handled) {
539 Item.dump(Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700540 Str << "\n";
541 }
542 Str << "++++++ Unhandled:\n";
Jim Stichnothf44f3712014-10-01 14:05:51 -0700543 for (const LiveRangeWrapper &Item : Unhandled) {
544 Item.dump(Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700545 Str << "\n";
546 }
547 Str << "++++++ Active:\n";
Jim Stichnothf44f3712014-10-01 14:05:51 -0700548 for (const LiveRangeWrapper &Item : Active) {
549 Item.dump(Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700550 Str << "\n";
551 }
552 Str << "++++++ Inactive:\n";
Jim Stichnothf44f3712014-10-01 14:05:51 -0700553 for (const LiveRangeWrapper &Item : Inactive) {
554 Item.dump(Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700555 Str << "\n";
556 }
557}
558
559} // end of namespace Ice