blob: c9a50dc97a41ecf1fc9d9f778a7a99d05060b31f [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"
Jim Stichnoth87ff3a12014-11-14 10:27:29 -080017#include "IceCfgNode.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070018#include "IceInst.h"
19#include "IceOperand.h"
20#include "IceRegAlloc.h"
21#include "IceTargetLowering.h"
22
23namespace Ice {
24
Jim Stichnothad403532014-09-25 12:44:17 -070025namespace {
26
Jim Stichnothe34d79d2015-01-12 09:00:50 -080027// TODO(stichnot): Statically choose the size based on the target
28// being compiled.
29const size_t REGS_SIZE = 32;
30
Jim Stichnothad403532014-09-25 12:44:17 -070031// Returns true if Var has any definitions within Item's live range.
Jim Stichnoth037fa1d2014-10-07 11:09:33 -070032// TODO(stichnot): Consider trimming the Definitions list similar to
33// how the live ranges are trimmed, since all the overlapsDefs() tests
34// are whether some variable's definitions overlap Cur, and trimming
35// is with respect Cur.start. Initial tests show no measurable
36// performance difference, so we'll keep the code simple for now.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070037bool overlapsDefs(const Cfg *Func, const Variable *Item, const Variable *Var) {
Jim Stichnoth037fa1d2014-10-07 11:09:33 -070038 const bool UseTrimmed = true;
39 VariablesMetadata *VMetadata = Func->getVMetadata();
Jim Stichnoth877b04e2014-10-15 15:13:06 -070040 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var))
41 if (Item->getLiveRange().overlapsInst(FirstDef->getNumber(), UseTrimmed))
42 return true;
43 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var);
Jim Stichnothad403532014-09-25 12:44:17 -070044 for (size_t i = 0; i < Defs.size(); ++i) {
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070045 if (Item->getLiveRange().overlapsInst(Defs[i]->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 Stichnothfa4efea2015-01-27 05:06:03 -080055 if (Func->isVerbose(IceV_LinearScan)) {
Jim Stichnoth037fa1d2014-10-07 11:09:33 -070056 VariablesMetadata *VMetadata = Func->getVMetadata();
Jim Stichnothad403532014-09-25 12:44:17 -070057 Ostream &Str = Func->getContext()->getStrDump();
58 Str << "Disabling Overlap due to " << Reason << " " << *Var
59 << " LIVE=" << Var->getLiveRange() << " Defs=";
Jim Stichnoth877b04e2014-10-15 15:13:06 -070060 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var))
61 Str << FirstDef->getNumber();
62 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var);
Jim Stichnothad403532014-09-25 12:44:17 -070063 for (size_t i = 0; i < Defs.size(); ++i) {
Jim Stichnoth877b04e2014-10-15 15:13:06 -070064 Str << "," << Defs[i]->getNumber();
Jim Stichnothad403532014-09-25 12:44:17 -070065 }
66 Str << "\n";
67 }
68}
69
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070070void dumpLiveRange(const Variable *Var, const Cfg *Func) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -070071 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -080072 return;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070073 Ostream &Str = Func->getContext()->getStrDump();
74 const static size_t BufLen = 30;
75 char buf[BufLen];
76 snprintf(buf, BufLen, "%2d", Var->getRegNumTmp());
77 Str << "R=" << buf << " V=";
78 Var->dump(Func);
79 Str << " Range=" << Var->getLiveRange();
Jim Stichnothe22f8232014-10-13 16:20:59 -070080}
81
Jim Stichnothad403532014-09-25 12:44:17 -070082} // end of anonymous namespace
83
Jim Stichnoth70d0a052014-11-14 15:53:46 -080084// Prepare for full register allocation of all variables. We depend
85// on liveness analysis to have calculated live ranges.
86void LinearScan::initForGlobal() {
Jim Stichnoth87ff3a12014-11-14 10:27:29 -080087 TimerMarker T(TimerStack::TT_initUnhandled, Func);
Jim Stichnoth70d0a052014-11-14 15:53:46 -080088 FindPreference = true;
89 FindOverlap = true;
Jim Stichnoth87ff3a12014-11-14 10:27:29 -080090 const VarList &Vars = Func->getVariables();
91 Unhandled.reserve(Vars.size());
Jim Stichnoth4ead35a2014-12-03 20:30:34 -080092 UnhandledPrecolored.reserve(Vars.size());
Jim Stichnoth70d0a052014-11-14 15:53:46 -080093 // Gather the live ranges of all variables and add them to the
94 // Unhandled set.
Jim Stichnoth87ff3a12014-11-14 10:27:29 -080095 for (Variable *Var : Vars) {
96 // Explicitly don't consider zero-weight variables, which are
97 // meant to be spill slots.
Jim Stichnothc6ead202015-02-24 09:30:30 -080098 if (Var->getWeight().isZero())
Jim Stichnoth87ff3a12014-11-14 10:27:29 -080099 continue;
100 // Don't bother if the variable has a null live range, which means
101 // it was never referenced.
102 if (Var->getLiveRange().isEmpty())
103 continue;
104 Var->untrimLiveRange();
105 Unhandled.push_back(Var);
106 if (Var->hasReg()) {
107 Var->setRegNumTmp(Var->getRegNum());
108 Var->setLiveRangeInfiniteWeight();
109 UnhandledPrecolored.push_back(Var);
110 }
111 }
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800112
113 // Build the (ordered) list of FakeKill instruction numbers.
114 Kills.clear();
115 for (CfgNode *Node : Func->getNodes()) {
Jim Stichnoth29841e82014-12-23 12:26:24 -0800116 for (Inst &I : Node->getInsts()) {
117 if (auto Kill = llvm::dyn_cast<InstFakeKill>(&I)) {
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800118 if (!Kill->isDeleted() && !Kill->getLinked()->isDeleted())
Jim Stichnoth29841e82014-12-23 12:26:24 -0800119 Kills.push_back(I.getNumber());
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800120 }
121 }
122 }
123}
124
125// Prepare for very simple register allocation of only infinite-weight
126// Variables while respecting pre-colored Variables. Some properties
127// we take advantage of:
128//
129// * Live ranges of interest consist of a single segment.
130//
131// * Live ranges of interest never span a call instruction.
132//
133// * Phi instructions are not considered because either phis have
134// already been lowered, or they don't contain any pre-colored or
135// infinite-weight Variables.
136//
137// * We don't need to renumber instructions before computing live
138// ranges because all the high-level ICE instructions are deleted
139// prior to lowering, and the low-level instructions are added in
140// monotonically increasing order.
141//
142// * There are no opportunities for register preference or allowing
143// overlap.
144//
145// Some properties we aren't (yet) taking advantage of:
146//
Jim Stichnothe6d24782014-12-19 05:42:24 -0800147// * Because live ranges are a single segment, the Inactive set will
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800148// always be empty, and the live range trimming operation is
149// unnecessary.
150//
151// * Calculating overlap of single-segment live ranges could be
152// optimized a bit.
153void LinearScan::initForInfOnly() {
154 TimerMarker T(TimerStack::TT_initUnhandled, Func);
155 FindPreference = false;
156 FindOverlap = false;
157 SizeT NumVars = 0;
158 const VarList &Vars = Func->getVariables();
159
160 // Iterate across all instructions and record the begin and end of
161 // the live range for each variable that is pre-colored or infinite
162 // weight.
163 std::vector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel);
164 std::vector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel);
165 for (CfgNode *Node : Func->getNodes()) {
Jim Stichnoth29841e82014-12-23 12:26:24 -0800166 for (Inst &Inst : Node->getInsts()) {
167 if (Inst.isDeleted())
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800168 continue;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800169 if (const Variable *Var = Inst.getDest()) {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800170 if (Var->hasReg() || Var->getWeight().isInf()) {
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800171 if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) {
Jim Stichnoth29841e82014-12-23 12:26:24 -0800172 LRBegin[Var->getIndex()] = Inst.getNumber();
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800173 ++NumVars;
174 }
175 }
176 }
Jim Stichnoth29841e82014-12-23 12:26:24 -0800177 for (SizeT I = 0; I < Inst.getSrcSize(); ++I) {
178 Operand *Src = Inst.getSrc(I);
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800179 SizeT NumVars = Src->getNumVars();
180 for (SizeT J = 0; J < NumVars; ++J) {
181 const Variable *Var = Src->getVar(J);
Jim Stichnothc6ead202015-02-24 09:30:30 -0800182 if (Var->hasReg() || Var->getWeight().isInf())
Jim Stichnoth29841e82014-12-23 12:26:24 -0800183 LREnd[Var->getIndex()] = Inst.getNumber();
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800184 }
185 }
186 }
187 }
188
189 Unhandled.reserve(NumVars);
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800190 UnhandledPrecolored.reserve(NumVars);
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800191 for (SizeT i = 0; i < Vars.size(); ++i) {
192 Variable *Var = Vars[i];
193 if (LRBegin[i] != Inst::NumberSentinel) {
194 assert(LREnd[i] != Inst::NumberSentinel);
195 Unhandled.push_back(Var);
196 Var->resetLiveRange();
197 const uint32_t WeightDelta = 1;
198 Var->addLiveRange(LRBegin[i], LREnd[i], WeightDelta);
199 Var->untrimLiveRange();
200 if (Var->hasReg()) {
201 Var->setRegNumTmp(Var->getRegNum());
202 Var->setLiveRangeInfiniteWeight();
203 UnhandledPrecolored.push_back(Var);
204 }
205 --NumVars;
206 }
207 }
208 // This isn't actually a fatal condition, but it would be nice to
209 // know if we somehow pre-calculated Unhandled's size wrong.
210 assert(NumVars == 0);
211
212 // Don't build up the list of Kills because we know that no
213 // infinite-weight Variable has a live range spanning a call.
214 Kills.clear();
215}
216
217void LinearScan::init(RegAllocKind Kind) {
218 Unhandled.clear();
219 UnhandledPrecolored.clear();
220 Handled.clear();
221 Inactive.clear();
222 Active.clear();
223
224 switch (Kind) {
225 case RAK_Global:
226 initForGlobal();
227 break;
228 case RAK_InfOnly:
229 initForInfOnly();
230 break;
231 }
232
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800233 struct CompareRanges {
234 bool operator()(const Variable *L, const Variable *R) {
235 InstNumberT Lstart = L->getLiveRange().getStart();
236 InstNumberT Rstart = R->getLiveRange().getStart();
237 if (Lstart == Rstart)
238 return L->getIndex() < R->getIndex();
239 return Lstart < Rstart;
240 }
241 };
242 // Do a reverse sort so that erasing elements (from the end) is fast.
243 std::sort(Unhandled.rbegin(), Unhandled.rend(), CompareRanges());
244 std::sort(UnhandledPrecolored.rbegin(), UnhandledPrecolored.rend(),
245 CompareRanges());
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800246
247 Handled.reserve(Unhandled.size());
248 Inactive.reserve(Unhandled.size());
249 Active.reserve(Unhandled.size());
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800250}
251
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700252// Implements the linear-scan algorithm. Based on "Linear Scan
253// Register Allocation in the Context of SSA Form and Register
254// Constraints" by Hanspeter Mössenböck and Michael Pfeiffer,
255// ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF . This
256// implementation is modified to take affinity into account and allow
257// two interfering variables to share the same register in certain
258// cases.
259//
Jim Stichnoth800dab22014-09-20 12:25:02 -0700260// Requires running Cfg::liveness(Liveness_Intervals) in
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700261// preparation. Results are assigned to Variable::RegNum for each
262// Variable.
Jim Stichnothe6d24782014-12-19 05:42:24 -0800263void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull,
264 bool Randomized) {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700265 TimerMarker T(TimerStack::TT_linearScan, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700266 assert(RegMaskFull.any()); // Sanity check
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800267 GlobalContext *Ctx = Func->getContext();
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700268 const bool Verbose = BuildDefs::dump() && Func->isVerbose(IceV_LinearScan);
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800269 if (Verbose)
270 Ctx->lockStr();
Jim Stichnoth800dab22014-09-20 12:25:02 -0700271 Func->resetCurrentNode();
Jim Stichnothad403532014-09-25 12:44:17 -0700272 VariablesMetadata *VMetadata = Func->getVMetadata();
Jim Stichnothe6d24782014-12-19 05:42:24 -0800273 const size_t NumRegisters = RegMaskFull.size();
274 llvm::SmallBitVector PreDefinedRegisters(NumRegisters);
275 if (Randomized) {
276 for (Variable *Var : UnhandledPrecolored) {
277 PreDefinedRegisters[Var->getRegNum()] = true;
278 }
279 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700280
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800281 // Build a LiveRange representing the Kills list.
Jim Stichnoth2a7fcbb2014-12-04 11:45:03 -0800282 LiveRange KillsRange(Kills);
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800283 KillsRange.untrim();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700284
285 // RegUses[I] is the number of live ranges (variables) that register
286 // I is currently assigned to. It can be greater than 1 as a result
Jim Stichnothc4554d72014-09-30 16:49:38 -0700287 // of AllowOverlap inference below.
Jim Stichnothe34d79d2015-01-12 09:00:50 -0800288 llvm::SmallVector<int, REGS_SIZE> RegUses(NumRegisters);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700289 // Unhandled is already set to all ranges in increasing order of
290 // start points.
291 assert(Active.empty());
292 assert(Inactive.empty());
293 assert(Handled.empty());
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800294 const TargetLowering::RegSetMask RegsInclude =
295 TargetLowering::RegSet_CallerSave;
296 const TargetLowering::RegSetMask RegsExclude = TargetLowering::RegSet_None;
297 const llvm::SmallBitVector KillsMask =
298 Func->getTarget()->getRegisterSet(RegsInclude, RegsExclude);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700299
300 while (!Unhandled.empty()) {
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700301 Variable *Cur = Unhandled.back();
Jim Stichnothe22f8232014-10-13 16:20:59 -0700302 Unhandled.pop_back();
Jim Stichnothc4554d72014-09-30 16:49:38 -0700303 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800304 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700305 Str << "\nConsidering ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700306 dumpLiveRange(Cur, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700307 Str << "\n";
308 }
309 const llvm::SmallBitVector RegMask =
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700310 RegMaskFull & Func->getTarget()->getRegisterSetForType(Cur->getType());
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800311 KillsRange.trim(Cur->getLiveRange().getStart());
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700312
313 // Check for precolored ranges. If Cur is precolored, it
314 // definitely gets that register. Previously processed live
315 // ranges would have avoided that register due to it being
316 // precolored. Future processed live ranges won't evict that
317 // register because the live range has infinite weight.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700318 if (Cur->hasReg()) {
319 int32_t RegNum = Cur->getRegNum();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700320 // RegNumTmp should have already been set above.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700321 assert(Cur->getRegNumTmp() == RegNum);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700322 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800323 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700324 Str << "Precoloring ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700325 dumpLiveRange(Cur, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700326 Str << "\n";
327 }
328 Active.push_back(Cur);
329 assert(RegUses[RegNum] >= 0);
330 ++RegUses[RegNum];
Jim Stichnoth541ba662014-10-02 12:58:21 -0700331 assert(!UnhandledPrecolored.empty());
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700332 assert(UnhandledPrecolored.back() == Cur);
Jim Stichnothe22f8232014-10-13 16:20:59 -0700333 UnhandledPrecolored.pop_back();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700334 continue;
335 }
336
337 // Check for active ranges that have expired or become inactive.
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800338 for (SizeT I = Active.size(); I > 0; --I) {
339 const SizeT Index = I - 1;
340 Variable *Item = Active[Index];
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700341 Item->trimLiveRange(Cur->getLiveRange().getStart());
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700342 bool Moved = false;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700343 if (Item->rangeEndsBefore(Cur)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700344 // Move Item from Active to Handled list.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700345 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800346 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700347 Str << "Expiring ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700348 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700349 Str << "\n";
350 }
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800351 moveItem(Active, Index, Handled);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700352 Moved = true;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700353 } else if (!Item->rangeOverlapsStart(Cur)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700354 // Move Item from Active to Inactive list.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700355 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800356 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700357 Str << "Inactivating ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700358 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700359 Str << "\n";
360 }
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800361 moveItem(Active, Index, Inactive);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700362 Moved = true;
363 }
364 if (Moved) {
365 // Decrement Item from RegUses[].
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700366 assert(Item->hasRegTmp());
367 int32_t RegNum = Item->getRegNumTmp();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700368 --RegUses[RegNum];
369 assert(RegUses[RegNum] >= 0);
370 }
371 }
372
373 // Check for inactive ranges that have expired or reactivated.
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800374 for (SizeT I = Inactive.size(); I > 0; --I) {
375 const SizeT Index = I - 1;
376 Variable *Item = Inactive[Index];
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700377 Item->trimLiveRange(Cur->getLiveRange().getStart());
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700378 if (Item->rangeEndsBefore(Cur)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700379 // Move Item from Inactive to Handled list.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700380 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800381 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700382 Str << "Expiring ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700383 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700384 Str << "\n";
385 }
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800386 moveItem(Inactive, Index, Handled);
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700387 } else if (Item->rangeOverlapsStart(Cur)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700388 // Move Item from Inactive to Active list.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700389 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800390 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700391 Str << "Reactivating ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700392 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700393 Str << "\n";
394 }
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800395 moveItem(Inactive, Index, Active);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700396 // Increment Item in RegUses[].
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700397 assert(Item->hasRegTmp());
398 int32_t RegNum = Item->getRegNumTmp();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700399 assert(RegUses[RegNum] >= 0);
400 ++RegUses[RegNum];
401 }
402 }
403
404 // Calculate available registers into Free[].
405 llvm::SmallBitVector Free = RegMask;
406 for (SizeT i = 0; i < RegMask.size(); ++i) {
407 if (RegUses[i] > 0)
408 Free[i] = false;
409 }
410
Jim Stichnothad403532014-09-25 12:44:17 -0700411 // Infer register preference and allowable overlap. Only form a
412 // preference when the current Variable has an unambiguous "first"
413 // definition. The preference is some source Variable of the
414 // defining instruction that either is assigned a register that is
415 // currently free, or that is assigned a register that is not free
416 // but overlap is allowed. Overlap is allowed when the Variable
417 // under consideration is single-definition, and its definition is
418 // a simple assignment - i.e., the register gets copied/aliased
419 // but is never modified. Furthermore, overlap is only allowed
420 // when preferred Variable definition instructions do not appear
421 // within the current Variable's live range.
Jim Stichnothae953202014-12-20 06:17:49 -0800422 Variable *Prefer = nullptr;
Jim Stichnothad403532014-09-25 12:44:17 -0700423 int32_t PreferReg = Variable::NoRegister;
424 bool AllowOverlap = false;
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800425 if (FindPreference) {
426 if (const Inst *DefInst = VMetadata->getFirstDefinition(Cur)) {
427 assert(DefInst->getDest() == Cur);
428 bool IsAssign = DefInst->isSimpleAssign();
429 bool IsSingleDef = !VMetadata->isMultiDef(Cur);
430 for (SizeT i = 0; i < DefInst->getSrcSize(); ++i) {
431 // TODO(stichnot): Iterate through the actual Variables of the
432 // instruction, not just the source operands. This could
433 // capture Load instructions, including address mode
434 // optimization, for Prefer (but not for AllowOverlap).
435 if (Variable *SrcVar = llvm::dyn_cast<Variable>(DefInst->getSrc(i))) {
436 int32_t SrcReg = SrcVar->getRegNumTmp();
437 // Only consider source variables that have (so far) been
438 // assigned a register. That register must be one in the
439 // RegMask set, e.g. don't try to prefer the stack pointer
440 // as a result of the stacksave intrinsic.
441 if (SrcVar->hasRegTmp() && RegMask[SrcReg]) {
442 if (FindOverlap && !Free[SrcReg]) {
443 // Don't bother trying to enable AllowOverlap if the
444 // register is already free.
445 AllowOverlap =
446 IsSingleDef && IsAssign && !overlapsDefs(Func, Cur, SrcVar);
447 }
448 if (AllowOverlap || Free[SrcReg]) {
449 Prefer = SrcVar;
450 PreferReg = SrcReg;
451 }
Jim Stichnothad403532014-09-25 12:44:17 -0700452 }
453 }
454 }
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800455 if (Verbose && Prefer) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800456 Ostream &Str = Ctx->getStrDump();
Jim Stichnoth9a04c072014-12-11 15:51:42 -0800457 Str << "Initial Prefer=";
458 Prefer->dump(Func);
459 Str << " R=" << PreferReg << " LIVE=" << Prefer->getLiveRange()
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800460 << " Overlap=" << AllowOverlap << "\n";
461 }
Jim Stichnothad403532014-09-25 12:44:17 -0700462 }
463 }
464
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700465 // Remove registers from the Free[] list where an Inactive range
466 // overlaps with the current range.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700467 for (const Variable *Item : Inactive) {
468 if (Item->rangeOverlaps(Cur)) {
469 int32_t RegNum = Item->getRegNumTmp();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700470 // Don't assert(Free[RegNum]) because in theory (though
471 // probably never in practice) there could be two inactive
Jim Stichnothc4554d72014-09-30 16:49:38 -0700472 // variables that were marked with AllowOverlap.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700473 Free[RegNum] = false;
Jim Stichnothad403532014-09-25 12:44:17 -0700474 // Disable AllowOverlap if an Inactive variable, which is not
475 // Prefer, shares Prefer's register, and has a definition
476 // within Cur's live range.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700477 if (AllowOverlap && Item != Prefer && RegNum == PreferReg &&
478 overlapsDefs(Func, Cur, Item)) {
Jim Stichnothad403532014-09-25 12:44:17 -0700479 AllowOverlap = false;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700480 dumpDisableOverlap(Func, Item, "Inactive");
Jim Stichnothad403532014-09-25 12:44:17 -0700481 }
482 }
483 }
484
485 // Disable AllowOverlap if an Active variable, which is not
486 // Prefer, shares Prefer's register, and has a definition within
487 // Cur's live range.
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800488 if (AllowOverlap) {
489 for (const Variable *Item : Active) {
490 int32_t RegNum = Item->getRegNumTmp();
491 if (Item != Prefer && RegNum == PreferReg &&
492 overlapsDefs(Func, Cur, Item)) {
493 AllowOverlap = false;
494 dumpDisableOverlap(Func, Item, "Active");
495 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700496 }
497 }
498
Jim Stichnothe34d79d2015-01-12 09:00:50 -0800499 llvm::SmallVector<RegWeight, REGS_SIZE> Weights(RegMask.size());
Jim Stichnoth541ba662014-10-02 12:58:21 -0700500
501 // Remove registers from the Free[] list where an Unhandled
502 // precolored range overlaps with the current range, and set those
503 // registers to infinite weight so that they aren't candidates for
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700504 // eviction. Cur->rangeEndsBefore(Item) is an early exit check
505 // that turns a guaranteed O(N^2) algorithm into expected linear
Jim Stichnoth541ba662014-10-02 12:58:21 -0700506 // complexity.
507 llvm::SmallBitVector PrecoloredUnhandledMask(RegMask.size());
508 // Note: PrecoloredUnhandledMask is only used for dumping.
Jim Stichnoth7e571362015-01-09 11:43:26 -0800509 for (Variable *Item : reverse_range(UnhandledPrecolored)) {
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700510 assert(Item->hasReg());
511 if (Cur->rangeEndsBefore(Item))
Jim Stichnothf44f3712014-10-01 14:05:51 -0700512 break;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700513 if (Item->rangeOverlaps(Cur)) {
514 int32_t ItemReg = Item->getRegNum(); // Note: not getRegNumTmp()
Jim Stichnoth541ba662014-10-02 12:58:21 -0700515 Weights[ItemReg].setWeight(RegWeight::Inf);
Jim Stichnothad403532014-09-25 12:44:17 -0700516 Free[ItemReg] = false;
Jim Stichnoth541ba662014-10-02 12:58:21 -0700517 PrecoloredUnhandledMask[ItemReg] = true;
Jim Stichnothad403532014-09-25 12:44:17 -0700518 // Disable AllowOverlap if the preferred register is one of
519 // these precolored unhandled overlapping ranges.
520 if (AllowOverlap && ItemReg == PreferReg) {
521 AllowOverlap = false;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700522 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled");
Jim Stichnothad403532014-09-25 12:44:17 -0700523 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700524 }
525 }
526
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800527 // Remove scratch registers from the Free[] list, and mark their
528 // Weights[] as infinite, if KillsRange overlaps Cur's live range.
529 const bool UseTrimmed = true;
530 if (Cur->getLiveRange().overlaps(KillsRange, UseTrimmed)) {
531 Free.reset(KillsMask);
532 for (int i = KillsMask.find_first(); i != -1;
533 i = KillsMask.find_next(i)) {
534 Weights[i].setWeight(RegWeight::Inf);
535 if (PreferReg == i)
536 AllowOverlap = false;
537 }
538 }
539
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700540 // Print info about physical register availability.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700541 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800542 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700543 for (SizeT i = 0; i < RegMask.size(); ++i) {
544 if (RegMask[i]) {
545 Str << Func->getTarget()->getRegName(i, IceType_i32)
Jim Stichnothca662e92014-07-10 15:32:36 -0700546 << "(U=" << RegUses[i] << ",F=" << Free[i]
Jim Stichnoth541ba662014-10-02 12:58:21 -0700547 << ",P=" << PrecoloredUnhandledMask[i] << ") ";
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700548 }
549 }
550 Str << "\n";
551 }
552
Jim Stichnothad403532014-09-25 12:44:17 -0700553 if (Prefer && (AllowOverlap || Free[PreferReg])) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700554 // First choice: a preferred register that is either free or is
555 // allowed to overlap with its linked variable.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700556 Cur->setRegNumTmp(PreferReg);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700557 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800558 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700559 Str << "Preferring ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700560 dumpLiveRange(Cur, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700561 Str << "\n";
562 }
563 assert(RegUses[PreferReg] >= 0);
564 ++RegUses[PreferReg];
565 Active.push_back(Cur);
566 } else if (Free.any()) {
567 // Second choice: any free register. TODO: After explicit
568 // affinity is considered, is there a strategy better than just
569 // picking the lowest-numbered available register?
570 int32_t RegNum = Free.find_first();
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700571 Cur->setRegNumTmp(RegNum);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700572 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800573 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700574 Str << "Allocating ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700575 dumpLiveRange(Cur, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700576 Str << "\n";
577 }
578 assert(RegUses[RegNum] >= 0);
579 ++RegUses[RegNum];
580 Active.push_back(Cur);
581 } else {
582 // Fallback: there are no free registers, so we look for the
583 // lowest-weight register and see if Cur has higher weight.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700584 // Check Active ranges.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700585 for (const Variable *Item : Active) {
586 assert(Item->rangeOverlaps(Cur));
587 int32_t RegNum = Item->getRegNumTmp();
588 assert(Item->hasRegTmp());
589 Weights[RegNum].addWeight(Item->getLiveRange().getWeight());
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700590 }
591 // Same as above, but check Inactive ranges instead of Active.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700592 for (const Variable *Item : Inactive) {
593 int32_t RegNum = Item->getRegNumTmp();
594 assert(Item->hasRegTmp());
595 if (Item->rangeOverlaps(Cur))
596 Weights[RegNum].addWeight(Item->getLiveRange().getWeight());
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700597 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700598
599 // All the weights are now calculated. Find the register with
600 // smallest weight.
601 int32_t MinWeightIndex = RegMask.find_first();
602 // MinWeightIndex must be valid because of the initial
603 // RegMask.any() test.
604 assert(MinWeightIndex >= 0);
605 for (SizeT i = MinWeightIndex + 1; i < Weights.size(); ++i) {
606 if (RegMask[i] && Weights[i] < Weights[MinWeightIndex])
607 MinWeightIndex = i;
608 }
609
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700610 if (Cur->getLiveRange().getWeight() <= Weights[MinWeightIndex]) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700611 // Cur doesn't have priority over any other live ranges, so
612 // don't allocate any register to it, and move it to the
613 // Handled state.
614 Handled.push_back(Cur);
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700615 if (Cur->getLiveRange().getWeight().isInf()) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700616 Func->setError("Unable to find a physical register for an "
617 "infinite-weight live range");
618 }
619 } else {
620 // Evict all live ranges in Active that register number
621 // MinWeightIndex is assigned to.
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800622 for (SizeT I = Active.size(); I > 0; --I) {
623 const SizeT Index = I - 1;
624 Variable *Item = Active[Index];
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700625 if (Item->getRegNumTmp() == MinWeightIndex) {
Jim Stichnothc4554d72014-09-30 16:49:38 -0700626 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800627 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700628 Str << "Evicting ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700629 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700630 Str << "\n";
631 }
632 --RegUses[MinWeightIndex];
633 assert(RegUses[MinWeightIndex] >= 0);
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700634 Item->setRegNumTmp(Variable::NoRegister);
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800635 moveItem(Active, Index, Handled);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700636 }
637 }
638 // Do the same for Inactive.
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800639 for (SizeT I = Inactive.size(); I > 0; --I) {
640 const SizeT Index = I - 1;
641 Variable *Item = Inactive[Index];
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700642 // Note: The Item->rangeOverlaps(Cur) clause is not part of the
Jim Stichnoth68e28192014-07-24 08:48:15 -0700643 // description of AssignMemLoc() in the original paper. But
644 // there doesn't seem to be any need to evict an inactive
645 // live range that doesn't overlap with the live range
646 // currently being considered. It's especially bad if we
647 // would end up evicting an infinite-weight but
648 // currently-inactive live range. The most common situation
649 // for this would be a scratch register kill set for call
650 // instructions.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700651 if (Item->getRegNumTmp() == MinWeightIndex &&
652 Item->rangeOverlaps(Cur)) {
Jim Stichnothc4554d72014-09-30 16:49:38 -0700653 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800654 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700655 Str << "Evicting ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700656 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700657 Str << "\n";
658 }
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700659 Item->setRegNumTmp(Variable::NoRegister);
Jim Stichnoth4ead35a2014-12-03 20:30:34 -0800660 moveItem(Inactive, Index, Handled);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700661 }
662 }
663 // Assign the register to Cur.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700664 Cur->setRegNumTmp(MinWeightIndex);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700665 assert(RegUses[MinWeightIndex] >= 0);
666 ++RegUses[MinWeightIndex];
667 Active.push_back(Cur);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700668 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800669 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700670 Str << "Allocating ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700671 dumpLiveRange(Cur, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700672 Str << "\n";
673 }
674 }
675 }
676 dump(Func);
677 }
678 // Move anything Active or Inactive to Handled for easier handling.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700679 for (Variable *I : Active)
Jim Stichnothf44f3712014-10-01 14:05:51 -0700680 Handled.push_back(I);
681 Active.clear();
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700682 for (Variable *I : Inactive)
Jim Stichnothf44f3712014-10-01 14:05:51 -0700683 Handled.push_back(I);
684 Inactive.clear();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700685 dump(Func);
686
Jim Stichnothe6d24782014-12-19 05:42:24 -0800687 llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters);
688 if (Randomized) {
689 Func->getTarget()->makeRandomRegisterPermutation(
690 Permutation, PreDefinedRegisters | ~RegMaskFull);
691 }
692
693 // Finish up by assigning RegNumTmp->RegNum (or a random permutation
694 // thereof) for each Variable.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700695 for (Variable *Item : Handled) {
696 int32_t RegNum = Item->getRegNumTmp();
Jim Stichnothe6d24782014-12-19 05:42:24 -0800697 int32_t AssignedRegNum = RegNum;
698
699 if (Randomized && Item->hasRegTmp() && !Item->hasReg()) {
700 AssignedRegNum = Permutation[RegNum];
701 }
Jim Stichnothc4554d72014-09-30 16:49:38 -0700702 if (Verbose) {
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800703 Ostream &Str = Ctx->getStrDump();
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700704 if (!Item->hasRegTmp()) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700705 Str << "Not assigning ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700706 Item->dump(Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700707 Str << "\n";
708 } else {
Jim Stichnothe6d24782014-12-19 05:42:24 -0800709 Str << (AssignedRegNum == Item->getRegNum() ? "Reassigning "
710 : "Assigning ")
711 << Func->getTarget()->getRegName(AssignedRegNum, IceType_i32)
712 << "(r" << AssignedRegNum << ") to ";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700713 Item->dump(Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700714 Str << "\n";
715 }
716 }
Jim Stichnothe6d24782014-12-19 05:42:24 -0800717 Item->setRegNum(AssignedRegNum);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700718 }
719
720 // TODO: Consider running register allocation one more time, with
721 // infinite registers, for two reasons. First, evicted live ranges
722 // get a second chance for a register. Second, it allows coalescing
723 // of stack slots. If there is no time budget for the second
724 // register allocation run, each unallocated variable just gets its
725 // own slot.
726 //
727 // Another idea for coalescing stack slots is to initialize the
728 // Unhandled list with just the unallocated variables, saving time
729 // but not offering second-chance opportunities.
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800730
731 if (Verbose)
732 Ctx->unlockStr();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700733}
734
735// ======================== Dump routines ======================== //
736
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700737void LinearScan::dump(Cfg *Func) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700738 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800739 return;
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800740 if (!Func->isVerbose(IceV_LinearScan))
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700741 return;
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800742 Ostream &Str = Func->getContext()->getStrDump();
Jim Stichnoth800dab22014-09-20 12:25:02 -0700743 Func->resetCurrentNode();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700744 Str << "**** Current regalloc state:\n";
745 Str << "++++++ Handled:\n";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700746 for (const Variable *Item : Handled) {
747 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700748 Str << "\n";
749 }
750 Str << "++++++ Unhandled:\n";
Jim Stichnoth7e571362015-01-09 11:43:26 -0800751 for (const Variable *Item : reverse_range(Unhandled)) {
752 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700753 Str << "\n";
754 }
755 Str << "++++++ Active:\n";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700756 for (const Variable *Item : Active) {
757 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700758 Str << "\n";
759 }
760 Str << "++++++ Inactive:\n";
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700761 for (const Variable *Item : Inactive) {
762 dumpLiveRange(Item, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700763 Str << "\n";
764 }
765}
766
767} // end of namespace Ice