Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: src/IceRegAlloc.cpp

Issue 1253833002: Subzero: Cleanly implement register allocation after phi lowering. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Improve translation-time performance Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceRegAlloc.h ('k') | src/IceTargetLowering.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceRegAlloc.cpp - Linear-scan implementation -----------===// 1 //===- subzero/src/IceRegAlloc.cpp - Linear-scan implementation -----------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 19 matching lines...) Expand all
30 // being compiled. 30 // being compiled.
31 constexpr size_t REGS_SIZE = 32; 31 constexpr size_t REGS_SIZE = 32;
32 32
33 // Returns true if Var has any definitions within Item's live range. 33 // Returns true if Var has any definitions within Item's live range.
34 // TODO(stichnot): Consider trimming the Definitions list similar to 34 // TODO(stichnot): Consider trimming the Definitions list similar to
35 // how the live ranges are trimmed, since all the overlapsDefs() tests 35 // how the live ranges are trimmed, since all the overlapsDefs() tests
36 // are whether some variable's definitions overlap Cur, and trimming 36 // are whether some variable's definitions overlap Cur, and trimming
37 // is with respect Cur.start. Initial tests show no measurable 37 // is with respect Cur.start. Initial tests show no measurable
38 // performance difference, so we'll keep the code simple for now. 38 // performance difference, so we'll keep the code simple for now.
39 bool overlapsDefs(const Cfg *Func, const Variable *Item, const Variable *Var) { 39 bool overlapsDefs(const Cfg *Func, const Variable *Item, const Variable *Var) {
40 const bool UseTrimmed = true; 40 constexpr bool UseTrimmed = true;
41 VariablesMetadata *VMetadata = Func->getVMetadata(); 41 VariablesMetadata *VMetadata = Func->getVMetadata();
42 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var)) 42 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var))
43 if (Item->getLiveRange().overlapsInst(FirstDef->getNumber(), UseTrimmed)) 43 if (Item->getLiveRange().overlapsInst(FirstDef->getNumber(), UseTrimmed))
44 return true; 44 return true;
45 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var); 45 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var);
46 for (size_t i = 0; i < Defs.size(); ++i) { 46 for (size_t i = 0; i < Defs.size(); ++i) {
47 if (Item->getLiveRange().overlapsInst(Defs[i]->getNumber(), UseTrimmed)) 47 if (Item->getLiveRange().overlapsInst(Defs[i]->getNumber(), UseTrimmed))
48 return true; 48 return true;
49 } 49 }
50 return false; 50 return false;
(...skipping 15 matching lines...) Expand all
66 Str << "," << Defs[i]->getNumber(); 66 Str << "," << Defs[i]->getNumber();
67 } 67 }
68 Str << "\n"; 68 Str << "\n";
69 } 69 }
70 } 70 }
71 71
72 void dumpLiveRange(const Variable *Var, const Cfg *Func) { 72 void dumpLiveRange(const Variable *Var, const Cfg *Func) {
73 if (!BuildDefs::dump()) 73 if (!BuildDefs::dump())
74 return; 74 return;
75 Ostream &Str = Func->getContext()->getStrDump(); 75 Ostream &Str = Func->getContext()->getStrDump();
76 const static size_t BufLen = 30; 76 char buf[30];
77 char buf[BufLen]; 77 snprintf(buf, llvm::array_lengthof(buf), "%2d", Var->getRegNumTmp());
78 snprintf(buf, BufLen, "%2d", Var->getRegNumTmp());
79 Str << "R=" << buf << " V="; 78 Str << "R=" << buf << " V=";
80 Var->dump(Func); 79 Var->dump(Func);
81 Str << " Range=" << Var->getLiveRange(); 80 Str << " Range=" << Var->getLiveRange();
82 } 81 }
83 82
84 } // end of anonymous namespace 83 } // end of anonymous namespace
85 84
86 // Prepare for full register allocation of all variables. We depend 85 // Prepare for full register allocation of all variables. We depend
87 // on liveness analysis to have calculated live ranges. 86 // on liveness analysis to have calculated live ranges.
88 void LinearScan::initForGlobal() { 87 void LinearScan::initForGlobal() {
89 TimerMarker T(TimerStack::TT_initUnhandled, Func); 88 TimerMarker T(TimerStack::TT_initUnhandled, Func);
90 FindPreference = true; 89 FindPreference = true;
91 FindOverlap = true; 90 // For full register allocation, normally we want to enable FindOverlap
91 // (meaning we look for opportunities for two overlapping live ranges to
92 // safely share the same register). However, we disable it for phi-lowering
93 // register allocation since no overlap opportunities should be available and
94 // it's more expensive to look for opportunities.
95 FindOverlap = (Kind != RAK_Phi);
92 const VarList &Vars = Func->getVariables(); 96 const VarList &Vars = Func->getVariables();
93 Unhandled.reserve(Vars.size()); 97 Unhandled.reserve(Vars.size());
94 UnhandledPrecolored.reserve(Vars.size()); 98 UnhandledPrecolored.reserve(Vars.size());
95 // Gather the live ranges of all variables and add them to the 99 // Gather the live ranges of all variables and add them to the
96 // Unhandled set. 100 // Unhandled set.
97 for (Variable *Var : Vars) { 101 for (Variable *Var : Vars) {
98 // Explicitly don't consider zero-weight variables, which are 102 // Explicitly don't consider zero-weight variables, which are
99 // meant to be spill slots. 103 // meant to be spill slots.
100 if (Var->getWeight().isZero()) 104 if (Var->getWeight().isZero())
101 continue; 105 continue;
102 // Don't bother if the variable has a null live range, which means 106 // Don't bother if the variable has a null live range, which means
103 // it was never referenced. 107 // it was never referenced.
104 if (Var->getLiveRange().isEmpty()) 108 if (Var->getLiveRange().isEmpty())
105 continue; 109 continue;
110 // Post phi lowering register allocation is only concerned with variables
111 // that are infinite-weight or pre-colored.
112 if (Kind == RAK_Phi && !Var->getWeight().isInf() && !Var->hasReg())
113 continue;
106 Var->untrimLiveRange(); 114 Var->untrimLiveRange();
107 Unhandled.push_back(Var); 115 Unhandled.push_back(Var);
108 if (Var->hasReg()) { 116 if (Var->hasReg()) {
109 Var->setRegNumTmp(Var->getRegNum()); 117 Var->setRegNumTmp(Var->getRegNum());
110 Var->setLiveRangeInfiniteWeight(); 118 Var->setLiveRangeInfiniteWeight();
111 UnhandledPrecolored.push_back(Var); 119 UnhandledPrecolored.push_back(Var);
112 } 120 }
113 } 121 }
114 122
115 // Build the (ordered) list of FakeKill instruction numbers. 123 // Build the (ordered) list of FakeKill instruction numbers.
116 Kills.clear(); 124 Kills.clear();
125 // Phi lowering should not be creating new call instructions, so there should
126 // be no infinite-weight not-yet-colored live ranges that span a call
127 // instruction, hence no need to construct the Kills list.
128 if (Kind == RAK_Phi)
129 return;
117 for (CfgNode *Node : Func->getNodes()) { 130 for (CfgNode *Node : Func->getNodes()) {
118 for (Inst &I : Node->getInsts()) { 131 for (Inst &I : Node->getInsts()) {
119 if (auto Kill = llvm::dyn_cast<InstFakeKill>(&I)) { 132 if (auto Kill = llvm::dyn_cast<InstFakeKill>(&I)) {
120 if (!Kill->isDeleted() && !Kill->getLinked()->isDeleted()) 133 if (!Kill->isDeleted() && !Kill->getLinked()->isDeleted())
121 Kills.push_back(I.getNumber()); 134 Kills.push_back(I.getNumber());
122 } 135 }
123 } 136 }
124 } 137 }
125 } 138 }
126 139
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 } 202 }
190 203
191 Unhandled.reserve(NumVars); 204 Unhandled.reserve(NumVars);
192 UnhandledPrecolored.reserve(NumVars); 205 UnhandledPrecolored.reserve(NumVars);
193 for (SizeT i = 0; i < Vars.size(); ++i) { 206 for (SizeT i = 0; i < Vars.size(); ++i) {
194 Variable *Var = Vars[i]; 207 Variable *Var = Vars[i];
195 if (LRBegin[i] != Inst::NumberSentinel) { 208 if (LRBegin[i] != Inst::NumberSentinel) {
196 assert(LREnd[i] != Inst::NumberSentinel); 209 assert(LREnd[i] != Inst::NumberSentinel);
197 Unhandled.push_back(Var); 210 Unhandled.push_back(Var);
198 Var->resetLiveRange(); 211 Var->resetLiveRange();
199 const uint32_t WeightDelta = 1; 212 constexpr uint32_t WeightDelta = 1;
200 Var->addLiveRange(LRBegin[i], LREnd[i], WeightDelta); 213 Var->addLiveRange(LRBegin[i], LREnd[i], WeightDelta);
201 Var->untrimLiveRange(); 214 Var->untrimLiveRange();
202 if (Var->hasReg()) { 215 if (Var->hasReg()) {
203 Var->setRegNumTmp(Var->getRegNum()); 216 Var->setRegNumTmp(Var->getRegNum());
204 Var->setLiveRangeInfiniteWeight(); 217 Var->setLiveRangeInfiniteWeight();
205 UnhandledPrecolored.push_back(Var); 218 UnhandledPrecolored.push_back(Var);
206 } 219 }
207 --NumVars; 220 --NumVars;
208 } 221 }
209 } 222 }
210 // This isn't actually a fatal condition, but it would be nice to 223 // This isn't actually a fatal condition, but it would be nice to
211 // know if we somehow pre-calculated Unhandled's size wrong. 224 // know if we somehow pre-calculated Unhandled's size wrong.
212 assert(NumVars == 0); 225 assert(NumVars == 0);
213 226
214 // Don't build up the list of Kills because we know that no 227 // Don't build up the list of Kills because we know that no
215 // infinite-weight Variable has a live range spanning a call. 228 // infinite-weight Variable has a live range spanning a call.
216 Kills.clear(); 229 Kills.clear();
217 } 230 }
218 231
219 void LinearScan::init(RegAllocKind Kind) { 232 void LinearScan::init(RegAllocKind Kind) {
233 this->Kind = Kind;
220 Unhandled.clear(); 234 Unhandled.clear();
221 UnhandledPrecolored.clear(); 235 UnhandledPrecolored.clear();
222 Handled.clear(); 236 Handled.clear();
223 Inactive.clear(); 237 Inactive.clear();
224 Active.clear(); 238 Active.clear();
225 239
226 switch (Kind) { 240 switch (Kind) {
241 case RAK_Unknown:
242 llvm::report_fatal_error("Invalid RAK_Unknown");
243 break;
227 case RAK_Global: 244 case RAK_Global:
245 case RAK_Phi:
228 initForGlobal(); 246 initForGlobal();
229 break; 247 break;
230 case RAK_InfOnly: 248 case RAK_InfOnly:
231 initForInfOnly(); 249 initForInfOnly();
232 break; 250 break;
233 } 251 }
234 252
235 struct CompareRanges { 253 struct CompareRanges {
236 bool operator()(const Variable *L, const Variable *R) { 254 bool operator()(const Variable *L, const Variable *R) {
237 InstNumberT Lstart = L->getLiveRange().getStart(); 255 InstNumberT Lstart = L->getLiveRange().getStart();
238 InstNumberT Rstart = R->getLiveRange().getStart(); 256 InstNumberT Rstart = R->getLiveRange().getStart();
239 if (Lstart == Rstart) 257 if (Lstart == Rstart)
240 return L->getIndex() < R->getIndex(); 258 return L->getIndex() < R->getIndex();
241 return Lstart < Rstart; 259 return Lstart < Rstart;
242 } 260 }
243 }; 261 };
244 // Do a reverse sort so that erasing elements (from the end) is fast. 262 // Do a reverse sort so that erasing elements (from the end) is fast.
245 std::sort(Unhandled.rbegin(), Unhandled.rend(), CompareRanges()); 263 std::sort(Unhandled.rbegin(), Unhandled.rend(), CompareRanges());
246 std::sort(UnhandledPrecolored.rbegin(), UnhandledPrecolored.rend(), 264 std::sort(UnhandledPrecolored.rbegin(), UnhandledPrecolored.rend(),
247 CompareRanges()); 265 CompareRanges());
248 266
249 Handled.reserve(Unhandled.size()); 267 Handled.reserve(Unhandled.size());
250 Inactive.reserve(Unhandled.size()); 268 Inactive.reserve(Unhandled.size());
251 Active.reserve(Unhandled.size()); 269 Active.reserve(Unhandled.size());
252 } 270 }
253 271
272 // This is called when Cur must be allocated a register but no registers are
273 // available across Cur's live range. To handle this, we find a register that
274 // is not explicitly used during Cur's live range, spill that register to a
275 // stack location right before Cur's live range begins, and fill (reload) the
276 // register from the stack location right after Cur's live range ends.
277 void LinearScan::addSpillFill(Variable *Cur, llvm::SmallBitVector RegMask) {
278 // Identify the actual instructions that begin and end Cur's live range.
279 // Iterate through Cur's node's instruction list until we find the actual
280 // instructions with instruction numbers corresponding to Cur's recorded live
281 // range endpoints. This sounds inefficient but shouldn't be a problem in
282 // practice because:
283 // (1) This function is almost never called in practice.
284 // (2) Since this register over-subscription problem happens only for
285 // phi-lowered instructions, the number of instructions in the node is
286 // proportional to the number of phi instructions in the original node,
287 // which is never very large in practice.
288 // (3) We still have to iterate through all instructions of Cur's live range
289 // to find all explicitly used registers (though the live range is usually
290 // only 2-3 instructions), so the main cost that could be avoided would be
291 // finding the instruction that begin's Cur's live range.
292 assert(!Cur->getLiveRange().isEmpty());
293 InstNumberT Start = Cur->getLiveRange().getStart();
294 InstNumberT End = Cur->getLiveRange().getEnd();
295 CfgNode *Node = Func->getVMetadata()->getLocalUseNode(Cur);
296 assert(Node);
297 InstList &Insts = Node->getInsts();
298 InstList::iterator SpillPoint = Insts.end();
299 InstList::iterator FillPoint = Insts.end();
300 // Stop searching after we have found both the SpillPoint and the FillPoint.
301 for (auto I = Insts.begin(), E = Insts.end();
302 I != E && (SpillPoint == E || FillPoint == E); ++I) {
303 if (I->getNumber() == Start)
304 SpillPoint = I;
305 if (I->getNumber() == End)
306 FillPoint = I;
307 if (SpillPoint != E) {
308 // Remove from RegMask any physical registers referenced during Cur's live
309 // range. Start looking after SpillPoint gets set, i.e. once Cur's live
310 // range begins.
311 for (SizeT i = 0; i < I->getSrcSize(); ++i) {
312 Operand *Src = I->getSrc(i);
313 SizeT NumVars = Src->getNumVars();
314 for (SizeT j = 0; j < NumVars; ++j) {
315 const Variable *Var = Src->getVar(j);
316 if (Var->hasRegTmp())
317 RegMask[Var->getRegNumTmp()] = false;
318 }
319 }
320 }
321 }
322 assert(SpillPoint != Insts.end());
323 assert(FillPoint != Insts.end());
324 ++FillPoint;
325 // TODO(stichnot): Randomize instead of find_first().
326 int32_t RegNum = RegMask.find_first();
327 assert(RegNum != -1);
328 Cur->setRegNumTmp(RegNum);
329 TargetLowering *Target = Func->getTarget();
330 Variable *Preg = Target->getPhysicalRegister(RegNum, Cur->getType());
331 // TODO(stichnot): Add SpillLoc to VariablesMetadata tracking so that SpillLoc
332 // is correctly identified as !isMultiBlock(), reducing stack frame size.
333 Variable *SpillLoc = Func->makeVariable(Cur->getType());
334 // Add "reg=FakeDef;spill=reg" before SpillPoint
335 Target->lowerInst(Node, SpillPoint, InstFakeDef::create(Func, Preg));
336 Target->lowerInst(Node, SpillPoint, InstAssign::create(Func, SpillLoc, Preg));
337 // add "reg=spill;FakeUse(reg)" before FillPoint
338 Target->lowerInst(Node, FillPoint, InstAssign::create(Func, Preg, SpillLoc));
339 Target->lowerInst(Node, FillPoint, InstFakeUse::create(Func, Preg));
340 }
341
254 // Implements the linear-scan algorithm. Based on "Linear Scan 342 // Implements the linear-scan algorithm. Based on "Linear Scan
255 // Register Allocation in the Context of SSA Form and Register 343 // Register Allocation in the Context of SSA Form and Register
256 // Constraints" by Hanspeter Mössenböck and Michael Pfeiffer, 344 // Constraints" by Hanspeter Mössenböck and Michael Pfeiffer,
257 // ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF . This 345 // ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF . This
258 // implementation is modified to take affinity into account and allow 346 // implementation is modified to take affinity into account and allow
259 // two interfering variables to share the same register in certain 347 // two interfering variables to share the same register in certain
260 // cases. 348 // cases.
261 // 349 //
262 // Requires running Cfg::liveness(Liveness_Intervals) in 350 // Requires running Cfg::liveness(Liveness_Intervals) in
263 // preparation. Results are assigned to Variable::RegNum for each 351 // preparation. Results are assigned to Variable::RegNum for each
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 if (Verbose) { 393 if (Verbose) {
306 Ostream &Str = Ctx->getStrDump(); 394 Ostream &Str = Ctx->getStrDump();
307 Str << "\nConsidering "; 395 Str << "\nConsidering ";
308 dumpLiveRange(Cur, Func); 396 dumpLiveRange(Cur, Func);
309 Str << "\n"; 397 Str << "\n";
310 } 398 }
311 const llvm::SmallBitVector RegMask = 399 const llvm::SmallBitVector RegMask =
312 RegMaskFull & Func->getTarget()->getRegisterSetForType(Cur->getType()); 400 RegMaskFull & Func->getTarget()->getRegisterSetForType(Cur->getType());
313 KillsRange.trim(Cur->getLiveRange().getStart()); 401 KillsRange.trim(Cur->getLiveRange().getStart());
314 402
315 // Check for precolored ranges. If Cur is precolored, it 403 // Check for pre-colored ranges. If Cur is pre-colored, it
316 // definitely gets that register. Previously processed live 404 // definitely gets that register. Previously processed live
317 // ranges would have avoided that register due to it being 405 // ranges would have avoided that register due to it being
318 // precolored. Future processed live ranges won't evict that 406 // pre-colored. Future processed live ranges won't evict that
319 // register because the live range has infinite weight. 407 // register because the live range has infinite weight.
320 if (Cur->hasReg()) { 408 if (Cur->hasReg()) {
321 int32_t RegNum = Cur->getRegNum(); 409 int32_t RegNum = Cur->getRegNum();
322 // RegNumTmp should have already been set above. 410 // RegNumTmp should have already been set above.
323 assert(Cur->getRegNumTmp() == RegNum); 411 assert(Cur->getRegNumTmp() == RegNum);
324 if (Verbose) { 412 if (Verbose) {
325 Ostream &Str = Ctx->getStrDump(); 413 Ostream &Str = Ctx->getStrDump();
326 Str << "Precoloring "; 414 Str << "Precoloring ";
327 dumpLiveRange(Cur, Func); 415 dumpLiveRange(Cur, Func);
328 Str << "\n"; 416 Str << "\n";
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 overlapsDefs(Func, Cur, Item)) { 582 overlapsDefs(Func, Cur, Item)) {
495 AllowOverlap = false; 583 AllowOverlap = false;
496 dumpDisableOverlap(Func, Item, "Active"); 584 dumpDisableOverlap(Func, Item, "Active");
497 } 585 }
498 } 586 }
499 } 587 }
500 588
501 llvm::SmallVector<RegWeight, REGS_SIZE> Weights(RegMask.size()); 589 llvm::SmallVector<RegWeight, REGS_SIZE> Weights(RegMask.size());
502 590
503 // Remove registers from the Free[] list where an Unhandled 591 // Remove registers from the Free[] list where an Unhandled
504 // precolored range overlaps with the current range, and set those 592 // pre-colored range overlaps with the current range, and set those
505 // registers to infinite weight so that they aren't candidates for 593 // registers to infinite weight so that they aren't candidates for
506 // eviction. Cur->rangeEndsBefore(Item) is an early exit check 594 // eviction. Cur->rangeEndsBefore(Item) is an early exit check
507 // that turns a guaranteed O(N^2) algorithm into expected linear 595 // that turns a guaranteed O(N^2) algorithm into expected linear
508 // complexity. 596 // complexity.
509 llvm::SmallBitVector PrecoloredUnhandledMask(RegMask.size()); 597 llvm::SmallBitVector PrecoloredUnhandledMask(RegMask.size());
510 // Note: PrecoloredUnhandledMask is only used for dumping. 598 // Note: PrecoloredUnhandledMask is only used for dumping.
511 for (Variable *Item : reverse_range(UnhandledPrecolored)) { 599 for (Variable *Item : reverse_range(UnhandledPrecolored)) {
512 assert(Item->hasReg()); 600 assert(Item->hasReg());
513 if (Cur->rangeEndsBefore(Item)) 601 if (Cur->rangeEndsBefore(Item))
514 break; 602 break;
515 if (Item->rangeOverlaps(Cur)) { 603 if (Item->rangeOverlaps(Cur)) {
516 int32_t ItemReg = Item->getRegNum(); // Note: not getRegNumTmp() 604 int32_t ItemReg = Item->getRegNum(); // Note: not getRegNumTmp()
517 Weights[ItemReg].setWeight(RegWeight::Inf); 605 Weights[ItemReg].setWeight(RegWeight::Inf);
518 Free[ItemReg] = false; 606 Free[ItemReg] = false;
519 PrecoloredUnhandledMask[ItemReg] = true; 607 PrecoloredUnhandledMask[ItemReg] = true;
520 // Disable AllowOverlap if the preferred register is one of 608 // Disable AllowOverlap if the preferred register is one of
521 // these precolored unhandled overlapping ranges. 609 // these pre-colored unhandled overlapping ranges.
522 if (AllowOverlap && ItemReg == PreferReg) { 610 if (AllowOverlap && ItemReg == PreferReg) {
523 AllowOverlap = false; 611 AllowOverlap = false;
524 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled"); 612 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled");
525 } 613 }
526 } 614 }
527 } 615 }
528 616
529 // Remove scratch registers from the Free[] list, and mark their 617 // Remove scratch registers from the Free[] list, and mark their
530 // Weights[] as infinite, if KillsRange overlaps Cur's live range. 618 // Weights[] as infinite, if KillsRange overlaps Cur's live range.
531 const bool UseTrimmed = true; 619 constexpr bool UseTrimmed = true;
532 if (Cur->getLiveRange().overlaps(KillsRange, UseTrimmed)) { 620 if (Cur->getLiveRange().overlaps(KillsRange, UseTrimmed)) {
533 Free.reset(KillsMask); 621 Free.reset(KillsMask);
534 for (int i = KillsMask.find_first(); i != -1; 622 for (int i = KillsMask.find_first(); i != -1;
535 i = KillsMask.find_next(i)) { 623 i = KillsMask.find_next(i)) {
536 Weights[i].setWeight(RegWeight::Inf); 624 Weights[i].setWeight(RegWeight::Inf);
537 if (PreferReg == i) 625 if (PreferReg == i)
538 AllowOverlap = false; 626 AllowOverlap = false;
539 } 627 }
540 } 628 }
541 629
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 if (RegMask[i] && Weights[i] < Weights[MinWeightIndex]) 696 if (RegMask[i] && Weights[i] < Weights[MinWeightIndex])
609 MinWeightIndex = i; 697 MinWeightIndex = i;
610 } 698 }
611 699
612 if (Cur->getLiveRange().getWeight() <= Weights[MinWeightIndex]) { 700 if (Cur->getLiveRange().getWeight() <= Weights[MinWeightIndex]) {
613 // Cur doesn't have priority over any other live ranges, so 701 // Cur doesn't have priority over any other live ranges, so
614 // don't allocate any register to it, and move it to the 702 // don't allocate any register to it, and move it to the
615 // Handled state. 703 // Handled state.
616 Handled.push_back(Cur); 704 Handled.push_back(Cur);
617 if (Cur->getLiveRange().getWeight().isInf()) { 705 if (Cur->getLiveRange().getWeight().isInf()) {
618 Func->setError("Unable to find a physical register for an " 706 if (Kind == RAK_Phi)
619 "infinite-weight live range"); 707 addSpillFill(Cur, RegMask);
708 else
709 Func->setError("Unable to find a physical register for an "
710 "infinite-weight live range");
620 } 711 }
621 } else { 712 } else {
622 // Evict all live ranges in Active that register number 713 // Evict all live ranges in Active that register number
623 // MinWeightIndex is assigned to. 714 // MinWeightIndex is assigned to.
624 for (SizeT I = Active.size(); I > 0; --I) { 715 for (SizeT I = Active.size(); I > 0; --I) {
625 const SizeT Index = I - 1; 716 const SizeT Index = I - 1;
626 Variable *Item = Active[Index]; 717 Variable *Item = Active[Index];
627 if (Item->getRegNumTmp() == MinWeightIndex) { 718 if (Item->getRegNumTmp() == MinWeightIndex) {
628 if (Verbose) { 719 if (Verbose) {
629 Ostream &Str = Ctx->getStrDump(); 720 Ostream &Str = Ctx->getStrDump();
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 Str << "\n"; 851 Str << "\n";
761 } 852 }
762 Str << "++++++ Inactive:\n"; 853 Str << "++++++ Inactive:\n";
763 for (const Variable *Item : Inactive) { 854 for (const Variable *Item : Inactive) {
764 dumpLiveRange(Item, Func); 855 dumpLiveRange(Item, Func);
765 Str << "\n"; 856 Str << "\n";
766 } 857 }
767 } 858 }
768 859
769 } // end of namespace Ice 860 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceRegAlloc.h ('k') | src/IceTargetLowering.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698