OLD | NEW |
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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 } | 270 } |
271 // This isn't actually a fatal condition, but it would be nice to know if we | 271 // This isn't actually a fatal condition, but it would be nice to know if we |
272 // somehow pre-calculated Unhandled's size wrong. | 272 // somehow pre-calculated Unhandled's size wrong. |
273 assert(NumVars == 0); | 273 assert(NumVars == 0); |
274 | 274 |
275 // Don't build up the list of Kills because we know that no infinite-weight | 275 // Don't build up the list of Kills because we know that no infinite-weight |
276 // Variable has a live range spanning a call. | 276 // Variable has a live range spanning a call. |
277 Kills.clear(); | 277 Kills.clear(); |
278 } | 278 } |
279 | 279 |
| 280 void LinearScan::initForSecondChance() { |
| 281 TimerMarker T(TimerStack::TT_initUnhandled, Func); |
| 282 FindPreference = true; |
| 283 FindOverlap = true; |
| 284 const VarList &Vars = Func->getVariables(); |
| 285 Unhandled.reserve(Vars.size()); |
| 286 UnhandledPrecolored.reserve(Vars.size()); |
| 287 for (Variable *Var : Vars) { |
| 288 if (Var->hasReg()) { |
| 289 Var->untrimLiveRange(); |
| 290 Var->setRegNumTmp(Var->getRegNum()); |
| 291 Var->setMustHaveReg(); |
| 292 UnhandledPrecolored.push_back(Var); |
| 293 Unhandled.push_back(Var); |
| 294 } |
| 295 } |
| 296 for (Variable *Var : Evicted) { |
| 297 Var->untrimLiveRange(); |
| 298 Unhandled.push_back(Var); |
| 299 } |
| 300 } |
| 301 |
280 void LinearScan::init(RegAllocKind Kind) { | 302 void LinearScan::init(RegAllocKind Kind) { |
281 this->Kind = Kind; | 303 this->Kind = Kind; |
282 Unhandled.clear(); | 304 Unhandled.clear(); |
283 UnhandledPrecolored.clear(); | 305 UnhandledPrecolored.clear(); |
284 Handled.clear(); | 306 Handled.clear(); |
285 Inactive.clear(); | 307 Inactive.clear(); |
286 Active.clear(); | 308 Active.clear(); |
287 | 309 |
288 SizeT NumRegs = Target->getNumRegisters(); | 310 SizeT NumRegs = Target->getNumRegisters(); |
289 RegAliases.resize(NumRegs); | 311 RegAliases.resize(NumRegs); |
290 for (SizeT Reg = 0; Reg < NumRegs; ++Reg) { | 312 for (SizeT Reg = 0; Reg < NumRegs; ++Reg) { |
291 RegAliases[Reg] = &Target->getAliasesForRegister(Reg); | 313 RegAliases[Reg] = &Target->getAliasesForRegister(Reg); |
292 } | 314 } |
293 | 315 |
294 switch (Kind) { | 316 switch (Kind) { |
295 case RAK_Unknown: | 317 case RAK_Unknown: |
296 llvm::report_fatal_error("Invalid RAK_Unknown"); | 318 llvm::report_fatal_error("Invalid RAK_Unknown"); |
297 break; | 319 break; |
298 case RAK_Global: | 320 case RAK_Global: |
299 case RAK_Phi: | 321 case RAK_Phi: |
300 initForGlobal(); | 322 initForGlobal(); |
301 break; | 323 break; |
302 case RAK_InfOnly: | 324 case RAK_InfOnly: |
303 initForInfOnly(); | 325 initForInfOnly(); |
304 break; | 326 break; |
| 327 case RAK_SecondChance: |
| 328 initForSecondChance(); |
| 329 break; |
305 } | 330 } |
306 | 331 |
| 332 Evicted.clear(); |
| 333 |
307 auto CompareRanges = [](const Variable *L, const Variable *R) { | 334 auto CompareRanges = [](const Variable *L, const Variable *R) { |
308 InstNumberT Lstart = L->getLiveRange().getStart(); | 335 InstNumberT Lstart = L->getLiveRange().getStart(); |
309 InstNumberT Rstart = R->getLiveRange().getStart(); | 336 InstNumberT Rstart = R->getLiveRange().getStart(); |
310 if (Lstart == Rstart) | 337 if (Lstart == Rstart) |
311 return L->getIndex() < R->getIndex(); | 338 return L->getIndex() < R->getIndex(); |
312 return Lstart < Rstart; | 339 return Lstart < Rstart; |
313 }; | 340 }; |
314 // Do a reverse sort so that erasing elements (from the end) is fast. | 341 // Do a reverse sort so that erasing elements (from the end) is fast. |
315 std::sort(Unhandled.rbegin(), Unhandled.rend(), CompareRanges); | 342 std::sort(Unhandled.rbegin(), Unhandled.rend(), CompareRanges); |
316 std::sort(UnhandledPrecolored.rbegin(), UnhandledPrecolored.rend(), | 343 std::sort(UnhandledPrecolored.rbegin(), UnhandledPrecolored.rend(), |
317 CompareRanges); | 344 CompareRanges); |
318 | 345 |
319 Handled.reserve(Unhandled.size()); | 346 Handled.reserve(Unhandled.size()); |
320 Inactive.reserve(Unhandled.size()); | 347 Inactive.reserve(Unhandled.size()); |
321 Active.reserve(Unhandled.size()); | 348 Active.reserve(Unhandled.size()); |
| 349 Evicted.reserve(Unhandled.size()); |
322 } | 350 } |
323 | 351 |
324 // This is called when Cur must be allocated a register but no registers are | 352 // This is called when Cur must be allocated a register but no registers are |
325 // available across Cur's live range. To handle this, we find a register that | 353 // available across Cur's live range. To handle this, we find a register that |
326 // is not explicitly used during Cur's live range, spill that register to a | 354 // is not explicitly used during Cur's live range, spill that register to a |
327 // stack location right before Cur's live range begins, and fill (reload) the | 355 // stack location right before Cur's live range begins, and fill (reload) the |
328 // register from the stack location right after Cur's live range ends. | 356 // register from the stack location right after Cur's live range ends. |
329 void LinearScan::addSpillFill(IterationState &Iter) { | 357 void LinearScan::addSpillFill(IterationState &Iter) { |
330 // Identify the actual instructions that begin and end Iter.Cur's live range. | 358 // Identify the actual instructions that begin and end Iter.Cur's live range. |
331 // Iterate through Iter.Cur's node's instruction list until we find the actual | 359 // Iterate through Iter.Cur's node's instruction list until we find the actual |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 for (SizeT I = Active.size(); I > 0; --I) { | 684 for (SizeT I = Active.size(); I > 0; --I) { |
657 const SizeT Index = I - 1; | 685 const SizeT Index = I - 1; |
658 Variable *Item = Active[Index]; | 686 Variable *Item = Active[Index]; |
659 int32_t RegNum = Item->getRegNumTmp(); | 687 int32_t RegNum = Item->getRegNumTmp(); |
660 if (Aliases[RegNum]) { | 688 if (Aliases[RegNum]) { |
661 dumpLiveRangeTrace("Evicting A ", Item); | 689 dumpLiveRangeTrace("Evicting A ", Item); |
662 --RegUses[RegNum]; | 690 --RegUses[RegNum]; |
663 assert(RegUses[RegNum] >= 0); | 691 assert(RegUses[RegNum] >= 0); |
664 Item->setRegNumTmp(Variable::NoRegister); | 692 Item->setRegNumTmp(Variable::NoRegister); |
665 moveItem(Active, Index, Handled); | 693 moveItem(Active, Index, Handled); |
| 694 Evicted.push_back(Item); |
666 } | 695 } |
667 } | 696 } |
668 // Do the same for Inactive. | 697 // Do the same for Inactive. |
669 for (SizeT I = Inactive.size(); I > 0; --I) { | 698 for (SizeT I = Inactive.size(); I > 0; --I) { |
670 const SizeT Index = I - 1; | 699 const SizeT Index = I - 1; |
671 Variable *Item = Inactive[Index]; | 700 Variable *Item = Inactive[Index]; |
672 // Note: The Item->rangeOverlaps(Cur) clause is not part of the | 701 // Note: The Item->rangeOverlaps(Cur) clause is not part of the |
673 // description of AssignMemLoc() in the original paper. But there doesn't | 702 // description of AssignMemLoc() in the original paper. But there doesn't |
674 // seem to be any need to evict an inactive live range that doesn't | 703 // seem to be any need to evict an inactive live range that doesn't |
675 // overlap with the live range currently being considered. It's | 704 // overlap with the live range currently being considered. It's |
676 // especially bad if we would end up evicting an infinite-weight but | 705 // especially bad if we would end up evicting an infinite-weight but |
677 // currently-inactive live range. The most common situation for this | 706 // currently-inactive live range. The most common situation for this |
678 // would be a scratch register kill set for call instructions. | 707 // would be a scratch register kill set for call instructions. |
679 if (Aliases[Item->getRegNumTmp()] && Item->rangeOverlaps(Iter.Cur)) { | 708 if (Aliases[Item->getRegNumTmp()] && Item->rangeOverlaps(Iter.Cur)) { |
680 dumpLiveRangeTrace("Evicting I ", Item); | 709 dumpLiveRangeTrace("Evicting I ", Item); |
681 Item->setRegNumTmp(Variable::NoRegister); | 710 Item->setRegNumTmp(Variable::NoRegister); |
682 moveItem(Inactive, Index, Handled); | 711 moveItem(Inactive, Index, Handled); |
| 712 Evicted.push_back(Item); |
683 } | 713 } |
684 } | 714 } |
685 // Assign the register to Cur. | 715 // Assign the register to Cur. |
686 Iter.Cur->setRegNumTmp(MinWeightIndex); | 716 Iter.Cur->setRegNumTmp(MinWeightIndex); |
687 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; | 717 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
688 RegAlias = Aliases.find_next(RegAlias)) { | 718 RegAlias = Aliases.find_next(RegAlias)) { |
689 assert(RegUses[RegAlias] >= 0); | 719 assert(RegUses[RegAlias] >= 0); |
690 ++RegUses[RegAlias]; | 720 ++RegUses[RegAlias]; |
691 } | 721 } |
692 Active.push_back(Iter.Cur); | 722 Active.push_back(Iter.Cur); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
940 Str << "\n"; | 970 Str << "\n"; |
941 } | 971 } |
942 Str << "++++++ Inactive:\n"; | 972 Str << "++++++ Inactive:\n"; |
943 for (const Variable *Item : Inactive) { | 973 for (const Variable *Item : Inactive) { |
944 dumpLiveRange(Item, Func); | 974 dumpLiveRange(Item, Func); |
945 Str << "\n"; | 975 Str << "\n"; |
946 } | 976 } |
947 } | 977 } |
948 | 978 |
949 } // end of namespace Ice | 979 } // end of namespace Ice |
OLD | NEW |