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

Side by Side Diff: src/IceRegAlloc.cpp

Issue 1310833003: Refactor LinearScan::scan from one huge function into smaller functions. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix randomization guards. 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
« src/IceRegAlloc.h ('K') | « src/IceRegAlloc.h ('k') | no next file » | 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
11 /// This file implements the LinearScan class, which performs the 11 /// This file implements the LinearScan class, which performs the linear-scan
Jim Stichnoth 2015/08/24 15:08:30 While you're at it, could you reformat all the oth
ascull 2015/08/24 19:53:47 Done.
12 /// linear-scan register allocation after liveness analysis has been 12 /// register allocation after liveness analysis has been performed.
13 /// performed.
14 /// 13 ///
15 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
16 15
17 #include "IceRegAlloc.h" 16 #include "IceRegAlloc.h"
18 17
19 #include "IceCfg.h" 18 #include "IceCfg.h"
20 #include "IceCfgNode.h" 19 #include "IceCfgNode.h"
21 #include "IceInst.h" 20 #include "IceInst.h"
22 #include "IceOperand.h" 21 #include "IceOperand.h"
23 #include "IceTargetLowering.h" 22 #include "IceTargetLowering.h"
24 23
25 namespace Ice { 24 namespace Ice {
26 25
27 namespace { 26 namespace {
28 27
29 // TODO(stichnot): Statically choose the size based on the target
30 // being compiled.
31 constexpr size_t REGS_SIZE = 32;
32
33 // Returns true if Var has any definitions within Item's live range. 28 // Returns true if Var has any definitions within Item's live range.
34 // TODO(stichnot): Consider trimming the Definitions list similar to 29 // TODO(stichnot): Consider trimming the Definitions list similar to how the
35 // how the live ranges are trimmed, since all the overlapsDefs() tests 30 // live ranges are trimmed, since all the overlapsDefs() tests are whether some
36 // are whether some variable's definitions overlap Cur, and trimming 31 // variable's definitions overlap Cur, and trimming is with respect Cur.start.
37 // is with respect Cur.start. Initial tests show no measurable 32 // Initial tests show no measurable performance difference, so we'll keep the
38 // performance difference, so we'll keep the code simple for now. 33 // code simple for now.
39 bool overlapsDefs(const Cfg *Func, const Variable *Item, const Variable *Var) { 34 bool overlapsDefs(const Cfg *Func, const Variable *Item, const Variable *Var) {
40 constexpr bool UseTrimmed = true; 35 constexpr bool UseTrimmed = true;
41 VariablesMetadata *VMetadata = Func->getVMetadata(); 36 VariablesMetadata *VMetadata = Func->getVMetadata();
42 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var)) 37 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var))
43 if (Item->getLiveRange().overlapsInst(FirstDef->getNumber(), UseTrimmed)) 38 if (Item->getLiveRange().overlapsInst(FirstDef->getNumber(), UseTrimmed))
44 return true; 39 return true;
45 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var); 40 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var);
46 for (size_t i = 0; i < Defs.size(); ++i) { 41 for (size_t i = 0; i < Defs.size(); ++i) {
47 if (Item->getLiveRange().overlapsInst(Defs[i]->getNumber(), UseTrimmed)) 42 if (Item->getLiveRange().overlapsInst(Defs[i]->getNumber(), UseTrimmed))
48 return true; 43 return true;
(...skipping 26 matching lines...) Expand all
75 Ostream &Str = Func->getContext()->getStrDump(); 70 Ostream &Str = Func->getContext()->getStrDump();
76 char buf[30]; 71 char buf[30];
77 snprintf(buf, llvm::array_lengthof(buf), "%2d", Var->getRegNumTmp()); 72 snprintf(buf, llvm::array_lengthof(buf), "%2d", Var->getRegNumTmp());
78 Str << "R=" << buf << " V="; 73 Str << "R=" << buf << " V=";
79 Var->dump(Func); 74 Var->dump(Func);
80 Str << " Range=" << Var->getLiveRange(); 75 Str << " Range=" << Var->getLiveRange();
81 } 76 }
82 77
83 } // end of anonymous namespace 78 } // end of anonymous namespace
84 79
80 LinearScan::LinearScan(Cfg *Func)
81 : Func(Func), Ctx(Func->getContext()),
82 Verbose(BuildDefs::dump() && Func->isVerbose(IceV_LinearScan)) {}
83
85 // Prepare for full register allocation of all variables. We depend 84 // Prepare for full register allocation of all variables. We depend
86 // on liveness analysis to have calculated live ranges. 85 // on liveness analysis to have calculated live ranges.
87 void LinearScan::initForGlobal() { 86 void LinearScan::initForGlobal() {
88 TimerMarker T(TimerStack::TT_initUnhandled, Func); 87 TimerMarker T(TimerStack::TT_initUnhandled, Func);
89 FindPreference = true; 88 FindPreference = true;
90 // For full register allocation, normally we want to enable FindOverlap 89 // For full register allocation, normally we want to enable FindOverlap
91 // (meaning we look for opportunities for two overlapping live ranges to 90 // (meaning we look for opportunities for two overlapping live ranges to
92 // safely share the same register). However, we disable it for phi-lowering 91 // safely share the same register). However, we disable it for phi-lowering
93 // register allocation since no overlap opportunities should be available and 92 // register allocation since no overlap opportunities should be available and
94 // it's more expensive to look for opportunities. 93 // it's more expensive to look for opportunities.
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 // is correctly identified as !isMultiBlock(), reducing stack frame size. 328 // is correctly identified as !isMultiBlock(), reducing stack frame size.
330 Variable *SpillLoc = Func->makeVariable(Cur->getType()); 329 Variable *SpillLoc = Func->makeVariable(Cur->getType());
331 // Add "reg=FakeDef;spill=reg" before SpillPoint 330 // Add "reg=FakeDef;spill=reg" before SpillPoint
332 Target->lowerInst(Node, SpillPoint, InstFakeDef::create(Func, Preg)); 331 Target->lowerInst(Node, SpillPoint, InstFakeDef::create(Func, Preg));
333 Target->lowerInst(Node, SpillPoint, InstAssign::create(Func, SpillLoc, Preg)); 332 Target->lowerInst(Node, SpillPoint, InstAssign::create(Func, SpillLoc, Preg));
334 // add "reg=spill;FakeUse(reg)" before FillPoint 333 // add "reg=spill;FakeUse(reg)" before FillPoint
335 Target->lowerInst(Node, FillPoint, InstAssign::create(Func, Preg, SpillLoc)); 334 Target->lowerInst(Node, FillPoint, InstAssign::create(Func, Preg, SpillLoc));
336 Target->lowerInst(Node, FillPoint, InstFakeUse::create(Func, Preg)); 335 Target->lowerInst(Node, FillPoint, InstFakeUse::create(Func, Preg));
337 } 336 }
338 337
339 // Implements the linear-scan algorithm. Based on "Linear Scan 338 void LinearScan::handleActiveRangeExpiredOrInactive(Variable *Cur) {
Jim Stichnoth 2015/08/24 15:08:30 const Variable *Cur
ascull 2015/08/24 19:53:47 Done.
340 // Register Allocation in the Context of SSA Form and Register 339 for (SizeT I = Active.size(); I > 0; --I) {
341 // Constraints" by Hanspeter Mössenböck and Michael Pfeiffer, 340 const SizeT Index = I - 1;
342 // ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF . This 341 Variable *Item = Active[Index];
343 // implementation is modified to take affinity into account and allow 342 Item->trimLiveRange(Cur->getLiveRange().getStart());
344 // two interfering variables to share the same register in certain 343 bool Moved = false;
345 // cases. 344 if (Item->rangeEndsBefore(Cur)) {
345 // Move Item from Active to Handled list.
346 if (Verbose) {
Jim Stichnoth 2015/08/24 15:08:31 Could you change every instance of "if (Verbose)"
ascull 2015/08/24 19:53:47 The initializer for Verbose includes `BuildDefs::d
347 Ostream &Str = Ctx->getStrDump();
348 Str << "Expiring ";
349 dumpLiveRange(Item, Func);
350 Str << "\n";
351 }
352 moveItem(Active, Index, Handled);
353 Moved = true;
354 } else if (!Item->rangeOverlapsStart(Cur)) {
355 // Move Item from Active to Inactive list.
356 if (Verbose) {
357 Ostream &Str = Ctx->getStrDump();
358 Str << "Inactivating ";
359 dumpLiveRange(Item, Func);
360 Str << "\n";
361 }
362 moveItem(Active, Index, Inactive);
363 Moved = true;
364 }
365 if (Moved) {
366 // Decrement Item from RegUses[].
367 assert(Item->hasRegTmp());
368 int32_t RegNum = Item->getRegNumTmp();
369 --RegUses[RegNum];
370 assert(RegUses[RegNum] >= 0);
371 }
372 }
373 }
374
375 void LinearScan::handleInctiveRangeExpiredOrReactived(Variable *Cur) {
Jim Stichnoth 2015/08/24 15:08:31 const Variable *Cur
ascull 2015/08/24 19:53:47 Done.
376 for (SizeT I = Inactive.size(); I > 0; --I) {
377 const SizeT Index = I - 1;
378 Variable *Item = Inactive[Index];
379 Item->trimLiveRange(Cur->getLiveRange().getStart());
380 if (Item->rangeEndsBefore(Cur)) {
381 // Move Item from Inactive to Handled list.
382 if (Verbose) {
383 Ostream &Str = Ctx->getStrDump();
384 Str << "Expiring ";
385 dumpLiveRange(Item, Func);
386 Str << "\n";
387 }
388 moveItem(Inactive, Index, Handled);
389 } else if (Item->rangeOverlapsStart(Cur)) {
390 // Move Item from Inactive to Active list.
391 if (Verbose) {
392 Ostream &Str = Ctx->getStrDump();
393 Str << "Reactivating ";
394 dumpLiveRange(Item, Func);
395 Str << "\n";
396 }
397 moveItem(Inactive, Index, Active);
398 // Increment Item in RegUses[].
399 assert(Item->hasRegTmp());
400 int32_t RegNum = Item->getRegNumTmp();
401 assert(RegUses[RegNum] >= 0);
402 ++RegUses[RegNum];
403 }
404 }
405 }
406
407 // Infer register preference and allowable overlap. Only form a preference when
408 // the current Variable has an unambiguous "first" definition. The preference
409 // is some source Variable of the defining instruction that either is assigned
410 // a register that is currently free, or that is assigned a register that is
411 // not free but overlap is allowed. Overlap is allowed when the Variable under
412 // consideration is single-definition, and its definition is a simple
413 // assignment - i.e., the register gets copied/aliased but is never modified.
414 // Furthermore, overlap is only allowed when preferred Variable definition
415 // instructions do not appear within the current Variable's live range.
416 void LinearScan::findRegisterPreference(Variable *Cur,
Jim Stichnoth 2015/08/24 15:08:31 const Variable *Cur
417 llvm::SmallBitVector RegMask) {
418 Prefer = nullptr;
419 PreferReg = Variable::NoRegister;
420 AllowOverlap = false;
421
422 if (FindPreference) {
423 VariablesMetadata *VMetadata = Func->getVMetadata();
424 if (const Inst *DefInst = VMetadata->getFirstDefinition(Cur)) {
425 assert(DefInst->getDest() == Cur);
426 bool IsAssign = DefInst->isSimpleAssign();
427 bool IsSingleDef = !VMetadata->isMultiDef(Cur);
428 for (SizeT i = 0; i < DefInst->getSrcSize(); ++i) {
429 // TODO(stichnot): Iterate through the actual Variables of the
430 // instruction, not just the source operands. This could capture Load
431 // instructions, including address mode optimization, for Prefer (but
432 // not for AllowOverlap).
433 if (Variable *SrcVar = llvm::dyn_cast<Variable>(DefInst->getSrc(i))) {
434 int32_t SrcReg = SrcVar->getRegNumTmp();
435 // Only consider source variables that have (so far) been assigned a
436 // register. That register must be one in the RegMask set, e.g.
437 // don't try to prefer the stack pointer as a result of the stacksave
438 // intrinsic.
439 if (SrcVar->hasRegTmp() && RegMask[SrcReg]) {
440 if (FindOverlap && !Free[SrcReg]) {
441 // Don't bother trying to enable AllowOverlap if the register is
442 // already free.
443 AllowOverlap =
444 IsSingleDef && IsAssign && !overlapsDefs(Func, Cur, SrcVar);
445 }
446 if (AllowOverlap || Free[SrcReg]) {
447 Prefer = SrcVar;
448 PreferReg = SrcReg;
449 }
450 }
451 }
452 }
453 if (Verbose && Prefer) {
454 Ostream &Str = Ctx->getStrDump();
455 Str << "Initial Prefer=";
456 Prefer->dump(Func);
457 Str << " R=" << PreferReg << " LIVE=" << Prefer->getLiveRange()
458 << " Overlap=" << AllowOverlap << "\n";
459 }
460 }
461 }
462 }
463
464 // Remove registers from the Free[] list where an Inactive range overlaps with
465 // the current range.
466 void LinearScan::filterFreeWithInactiveRanges(Variable *Cur) {
Jim Stichnoth 2015/08/24 15:08:30 const Variable *Cur
467 for (const Variable *Item : Inactive) {
468 if (Item->rangeOverlaps(Cur)) {
469 int32_t RegNum = Item->getRegNumTmp();
470 // Don't assert(Free[RegNum]) because in theory (though probably never in
471 // practice) there could be two inactive variables that were marked with
472 // AllowOverlap.
473 Free[RegNum] = false;
474 // Disable AllowOverlap if an Inactive variable, which is not Prefer,
475 // shares Prefer's register, and has a definition within Cur's live
476 // range.
477 if (AllowOverlap && Item != Prefer && RegNum == PreferReg &&
478 overlapsDefs(Func, Cur, Item)) {
479 AllowOverlap = false;
480 dumpDisableOverlap(Func, Item, "Inactive");
481 }
482 }
483 }
484 }
485
486 // Remove registers from the Free[] list where an Unhandled pre-colored range
487 // overlaps with the current range, and set those registers to infinite weight
488 // so that they aren't candidates for eviction. Cur->rangeEndsBefore(Item) is
489 // an early exit check that turns a guaranteed O(N^2) algorithm into expected
490 // linear complexity.
491 void LinearScan::filterFreeWithPrecoloredRanges(Variable *Cur) {
Jim Stichnoth 2015/08/24 15:08:30 const Variable *Cur
492 for (Variable *Item : reverse_range(UnhandledPrecolored)) {
493 assert(Item->hasReg());
494 if (Cur->rangeEndsBefore(Item))
495 break;
496 if (Item->rangeOverlaps(Cur)) {
497 int32_t ItemReg = Item->getRegNum(); // Note: not getRegNumTmp()
498 Weights[ItemReg].setWeight(RegWeight::Inf);
499 Free[ItemReg] = false;
500 PrecoloredUnhandledMask[ItemReg] = true;
501 // Disable AllowOverlap if the preferred register is one of
502 // these pre-colored unhandled overlapping ranges.
503 if (AllowOverlap && ItemReg == PreferReg) {
504 AllowOverlap = false;
505 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled");
506 }
507 }
508 }
509 }
510
511 void LinearScan::allocatePrecoloredRegister(Variable *Cur) {
512 int32_t RegNum = Cur->getRegNum();
513 // RegNumTmp should have already been set above.
514 assert(Cur->getRegNumTmp() == RegNum);
515 if (Verbose) {
516 Ostream &Str = Ctx->getStrDump();
517 Str << "Precoloring ";
518 dumpLiveRange(Cur, Func);
519 Str << "\n";
520 }
521 Active.push_back(Cur);
522 assert(RegUses[RegNum] >= 0);
523 ++RegUses[RegNum];
524 assert(!UnhandledPrecolored.empty());
525 assert(UnhandledPrecolored.back() == Cur);
526 UnhandledPrecolored.pop_back();
527 }
528
529 void LinearScan::allocatePreferedRegister(Variable *Cur) {
530 Cur->setRegNumTmp(PreferReg);
531 if (Verbose) {
532 Ostream &Str = Ctx->getStrDump();
533 Str << "Preferring ";
534 dumpLiveRange(Cur, Func);
535 Str << "\n";
536 }
537 assert(RegUses[PreferReg] >= 0);
538 ++RegUses[PreferReg];
539 Active.push_back(Cur);
540 }
541
542 void LinearScan::allocateFreeRegister(Variable *Cur) {
543 int32_t RegNum = Free.find_first();
544 Cur->setRegNumTmp(RegNum);
545 if (Verbose) {
546 Ostream &Str = Ctx->getStrDump();
547 Str << "Allocating ";
548 dumpLiveRange(Cur, Func);
549 Str << "\n";
550 }
551 assert(RegUses[RegNum] >= 0);
552 ++RegUses[RegNum];
553 Active.push_back(Cur);
554 }
555
556 void LinearScan::handleNoFreeRegisters(Variable *Cur,
557 llvm::SmallBitVector RegMask) {
558 // Check Active ranges.
559 for (const Variable *Item : Active) {
560 assert(Item->rangeOverlaps(Cur));
561 int32_t RegNum = Item->getRegNumTmp();
562 assert(Item->hasRegTmp());
563 Weights[RegNum].addWeight(Item->getLiveRange().getWeight());
564 }
565 // Same as above, but check Inactive ranges instead of Active.
566 for (const Variable *Item : Inactive) {
567 int32_t RegNum = Item->getRegNumTmp();
568 assert(Item->hasRegTmp());
569 if (Item->rangeOverlaps(Cur))
570 Weights[RegNum].addWeight(Item->getLiveRange().getWeight());
571 }
572
573 // All the weights are now calculated. Find the register with smallest
574 // weight.
575 int32_t MinWeightIndex = RegMask.find_first();
576 // MinWeightIndex must be valid because of the initial RegMask.any() test.
577 assert(MinWeightIndex >= 0);
578 for (SizeT i = MinWeightIndex + 1; i < Weights.size(); ++i) {
579 if (RegMask[i] && Weights[i] < Weights[MinWeightIndex])
580 MinWeightIndex = i;
581 }
582
583 if (Cur->getLiveRange().getWeight() <= Weights[MinWeightIndex]) {
584 // Cur doesn't have priority over any other live ranges, so don't allocate
585 // any register to it, and move it to the Handled state.
586 Handled.push_back(Cur);
587 if (Cur->getLiveRange().getWeight().isInf()) {
588 if (Kind == RAK_Phi)
589 addSpillFill(Cur, RegMask);
590 else
591 Func->setError("Unable to find a physical register for an "
592 "infinite-weight live range");
593 }
594 } else {
595 // Evict all live ranges in Active that register number MinWeightIndex is
596 // assigned to.
597 for (SizeT I = Active.size(); I > 0; --I) {
598 const SizeT Index = I - 1;
599 Variable *Item = Active[Index];
600 if (Item->getRegNumTmp() == MinWeightIndex) {
601 if (Verbose) {
602 Ostream &Str = Ctx->getStrDump();
603 Str << "Evicting ";
604 dumpLiveRange(Item, Func);
605 Str << "\n";
606 }
607 --RegUses[MinWeightIndex];
608 assert(RegUses[MinWeightIndex] >= 0);
609 Item->setRegNumTmp(Variable::NoRegister);
610 moveItem(Active, Index, Handled);
611 }
612 }
613 // Do the same for Inactive.
614 for (SizeT I = Inactive.size(); I > 0; --I) {
615 const SizeT Index = I - 1;
616 Variable *Item = Inactive[Index];
617 // Note: The Item->rangeOverlaps(Cur) clause is not part of the
618 // description of AssignMemLoc() in the original paper. But there
619 // doesn't seem to be any need to evict an inactive live range that
620 // doesn't overlap with the live range currently being considered. It's
621 // especially bad if we would end up evicting an infinite-weight but
622 // currently-inactive live range. The most common situation for this
623 // would be a scratch register kill set for call instructions.
624 if (Item->getRegNumTmp() == MinWeightIndex && Item->rangeOverlaps(Cur)) {
625 if (Verbose) {
626 Ostream &Str = Ctx->getStrDump();
627 Str << "Evicting ";
628 dumpLiveRange(Item, Func);
629 Str << "\n";
630 }
631 Item->setRegNumTmp(Variable::NoRegister);
632 moveItem(Inactive, Index, Handled);
633 }
634 }
635 // Assign the register to Cur.
636 Cur->setRegNumTmp(MinWeightIndex);
637 assert(RegUses[MinWeightIndex] >= 0);
638 ++RegUses[MinWeightIndex];
639 Active.push_back(Cur);
640 if (Verbose) {
641 Ostream &Str = Ctx->getStrDump();
642 Str << "Allocating ";
643 dumpLiveRange(Cur, Func);
644 Str << "\n";
645 }
646 }
647 }
648
649 void LinearScan::assignFinalRegisters(llvm::SmallBitVector RegMaskFull,
650 llvm::SmallBitVector PreDefinedRegisters,
651 bool Randomized) {
652 const size_t NumRegisters = RegMaskFull.size();
653 llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters);
654 if (Randomized) {
655 // Create a random number generator for regalloc randomization. Merge
656 // function's sequence and Kind value as the Salt. Because regAlloc() is
657 // called twice under O2, the second time with RAK_Phi, we check
658 // Kind == RAK_Phi to determine the lowest-order bit to make sure the Salt
659 // is different.
660 uint64_t Salt =
661 (Func->getSequenceNumber() << 1) ^ (Kind == RAK_Phi ? 0u : 1u);
662 Func->getTarget()->makeRandomRegisterPermutation(
663 Permutation, PreDefinedRegisters | ~RegMaskFull, Salt);
664 }
665
666 // Finish up by assigning RegNumTmp->RegNum (or a random permutation thereof)
jvoung (off chromium) 2015/08/24 15:33:01 nit: I think this was from the original comment, b
ascull 2015/08/24 19:53:47 Done.
667 // for each Variable.
668 for (Variable *Item : Handled) {
669 int32_t RegNum = Item->getRegNumTmp();
670 int32_t AssignedRegNum = RegNum;
671
672 if (Randomized && Item->hasRegTmp() && !Item->hasReg()) {
673 AssignedRegNum = Permutation[RegNum];
674 }
675 if (Verbose) {
676 Ostream &Str = Ctx->getStrDump();
677 if (!Item->hasRegTmp()) {
678 Str << "Not assigning ";
679 Item->dump(Func);
680 Str << "\n";
681 } else {
682 Str << (AssignedRegNum == Item->getRegNum() ? "Reassigning "
683 : "Assigning ")
684 << Func->getTarget()->getRegName(AssignedRegNum, IceType_i32)
685 << "(r" << AssignedRegNum << ") to ";
686 Item->dump(Func);
687 Str << "\n";
688 }
689 }
690 Item->setRegNum(AssignedRegNum);
691 }
692 }
693
694 // Implements the linear-scan algorithm. Based on "Linear Scan Register
695 // Allocation in the Context of SSA Form and Register Constraints" by Hanspeter
696 // Mössenböck and Michael Pfeiffer,
697 // ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF. This implementation is
698 // modified to take affinity into account and allow two interfering variables
699 // to share the same register in certain cases.
346 // 700 //
347 // Requires running Cfg::liveness(Liveness_Intervals) in 701 // Requires running Cfg::liveness(Liveness_Intervals) in preparation. Results
348 // preparation. Results are assigned to Variable::RegNum for each 702 // are assigned to Variable::RegNum for each Variable.
349 // Variable.
350 void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull, 703 void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull,
351 bool Randomized) { 704 bool Randomized) {
352 TimerMarker T(TimerStack::TT_linearScan, Func); 705 TimerMarker T(TimerStack::TT_linearScan, Func);
353 assert(RegMaskFull.any()); // Sanity check 706 assert(RegMaskFull.any()); // Sanity check
354 GlobalContext *Ctx = Func->getContext();
355 const bool Verbose = BuildDefs::dump() && Func->isVerbose(IceV_LinearScan);
356 if (Verbose) 707 if (Verbose)
357 Ctx->lockStr(); 708 Ctx->lockStr();
358 Func->resetCurrentNode(); 709 Func->resetCurrentNode();
359 VariablesMetadata *VMetadata = Func->getVMetadata();
360 const size_t NumRegisters = RegMaskFull.size(); 710 const size_t NumRegisters = RegMaskFull.size();
361 llvm::SmallBitVector PreDefinedRegisters(NumRegisters); 711 llvm::SmallBitVector PreDefinedRegisters(NumRegisters);
362 if (Randomized) { 712 if (Randomized) {
363 for (Variable *Var : UnhandledPrecolored) { 713 for (Variable *Var : UnhandledPrecolored) {
364 PreDefinedRegisters[Var->getRegNum()] = true; 714 PreDefinedRegisters[Var->getRegNum()] = true;
365 } 715 }
366 } 716 }
367 717
368 // Build a LiveRange representing the Kills list. 718 // Build a LiveRange representing the Kills list.
369 LiveRange KillsRange(Kills); 719 LiveRange KillsRange(Kills);
370 KillsRange.untrim(); 720 KillsRange.untrim();
371 721
372 // RegUses[I] is the number of live ranges (variables) that register 722 // Reset the register use count
373 // I is currently assigned to. It can be greater than 1 as a result 723 RegUses.resize(NumRegisters);
374 // of AllowOverlap inference below. 724 std::fill(RegUses.begin(), RegUses.end(), 0);
375 llvm::SmallVector<int, REGS_SIZE> RegUses(NumRegisters); 725
376 // Unhandled is already set to all ranges in increasing order of 726 // Unhandled is already set to all ranges in increasing order of start
377 // start points. 727 // points.
378 assert(Active.empty()); 728 assert(Active.empty());
379 assert(Inactive.empty()); 729 assert(Inactive.empty());
380 assert(Handled.empty()); 730 assert(Handled.empty());
381 const TargetLowering::RegSetMask RegsInclude = 731 const TargetLowering::RegSetMask RegsInclude =
382 TargetLowering::RegSet_CallerSave; 732 TargetLowering::RegSet_CallerSave;
383 const TargetLowering::RegSetMask RegsExclude = TargetLowering::RegSet_None; 733 const TargetLowering::RegSetMask RegsExclude = TargetLowering::RegSet_None;
384 const llvm::SmallBitVector KillsMask = 734 const llvm::SmallBitVector KillsMask =
385 Func->getTarget()->getRegisterSet(RegsInclude, RegsExclude); 735 Func->getTarget()->getRegisterSet(RegsInclude, RegsExclude);
386 736
387 while (!Unhandled.empty()) { 737 while (!Unhandled.empty()) {
388 Variable *Cur = Unhandled.back(); 738 Variable *Cur = Unhandled.back();
389 Unhandled.pop_back(); 739 Unhandled.pop_back();
390 if (Verbose) { 740 if (Verbose) {
391 Ostream &Str = Ctx->getStrDump(); 741 Ostream &Str = Ctx->getStrDump();
392 Str << "\nConsidering "; 742 Str << "\nConsidering ";
393 dumpLiveRange(Cur, Func); 743 dumpLiveRange(Cur, Func);
394 Str << "\n"; 744 Str << "\n";
395 } 745 }
396 const llvm::SmallBitVector RegMask = 746 const llvm::SmallBitVector RegMask =
397 RegMaskFull & Func->getTarget()->getRegisterSetForType(Cur->getType()); 747 RegMaskFull & Func->getTarget()->getRegisterSetForType(Cur->getType());
398 KillsRange.trim(Cur->getLiveRange().getStart()); 748 KillsRange.trim(Cur->getLiveRange().getStart());
399 749
400 // Check for pre-colored ranges. If Cur is pre-colored, it 750 // Check for pre-colored ranges. If Cur is pre-colored, it definitely gets
401 // definitely gets that register. Previously processed live 751 // that register. Previously processed live ranges would have avoided that
402 // ranges would have avoided that register due to it being 752 // register due to it being pre-colored. Future processed live ranges won't
403 // pre-colored. Future processed live ranges won't evict that 753 // evict that register because the live range has infinite weight.
404 // register because the live range has infinite weight.
405 if (Cur->hasReg()) { 754 if (Cur->hasReg()) {
406 int32_t RegNum = Cur->getRegNum(); 755 allocatePrecoloredRegister(Cur);
407 // RegNumTmp should have already been set above.
408 assert(Cur->getRegNumTmp() == RegNum);
409 if (Verbose) {
410 Ostream &Str = Ctx->getStrDump();
411 Str << "Precoloring ";
412 dumpLiveRange(Cur, Func);
413 Str << "\n";
414 }
415 Active.push_back(Cur);
416 assert(RegUses[RegNum] >= 0);
417 ++RegUses[RegNum];
418 assert(!UnhandledPrecolored.empty());
419 assert(UnhandledPrecolored.back() == Cur);
420 UnhandledPrecolored.pop_back();
421 continue; 756 continue;
422 } 757 }
423 758
424 // Check for active ranges that have expired or become inactive. 759 handleActiveRangeExpiredOrInactive(Cur);
425 for (SizeT I = Active.size(); I > 0; --I) { 760 handleInctiveRangeExpiredOrReactived(Cur);
426 const SizeT Index = I - 1;
427 Variable *Item = Active[Index];
428 Item->trimLiveRange(Cur->getLiveRange().getStart());
429 bool Moved = false;
430 if (Item->rangeEndsBefore(Cur)) {
431 // Move Item from Active to Handled list.
432 if (Verbose) {
433 Ostream &Str = Ctx->getStrDump();
434 Str << "Expiring ";
435 dumpLiveRange(Item, Func);
436 Str << "\n";
437 }
438 moveItem(Active, Index, Handled);
439 Moved = true;
440 } else if (!Item->rangeOverlapsStart(Cur)) {
441 // Move Item from Active to Inactive list.
442 if (Verbose) {
443 Ostream &Str = Ctx->getStrDump();
444 Str << "Inactivating ";
445 dumpLiveRange(Item, Func);
446 Str << "\n";
447 }
448 moveItem(Active, Index, Inactive);
449 Moved = true;
450 }
451 if (Moved) {
452 // Decrement Item from RegUses[].
453 assert(Item->hasRegTmp());
454 int32_t RegNum = Item->getRegNumTmp();
455 --RegUses[RegNum];
456 assert(RegUses[RegNum] >= 0);
457 }
458 }
459
460 // Check for inactive ranges that have expired or reactivated.
461 for (SizeT I = Inactive.size(); I > 0; --I) {
462 const SizeT Index = I - 1;
463 Variable *Item = Inactive[Index];
464 Item->trimLiveRange(Cur->getLiveRange().getStart());
465 if (Item->rangeEndsBefore(Cur)) {
466 // Move Item from Inactive to Handled list.
467 if (Verbose) {
468 Ostream &Str = Ctx->getStrDump();
469 Str << "Expiring ";
470 dumpLiveRange(Item, Func);
471 Str << "\n";
472 }
473 moveItem(Inactive, Index, Handled);
474 } else if (Item->rangeOverlapsStart(Cur)) {
475 // Move Item from Inactive to Active list.
476 if (Verbose) {
477 Ostream &Str = Ctx->getStrDump();
478 Str << "Reactivating ";
479 dumpLiveRange(Item, Func);
480 Str << "\n";
481 }
482 moveItem(Inactive, Index, Active);
483 // Increment Item in RegUses[].
484 assert(Item->hasRegTmp());
485 int32_t RegNum = Item->getRegNumTmp();
486 assert(RegUses[RegNum] >= 0);
487 ++RegUses[RegNum];
488 }
489 }
490 761
491 // Calculate available registers into Free[]. 762 // Calculate available registers into Free[].
492 llvm::SmallBitVector Free = RegMask; 763 Free = RegMask;
493 for (SizeT i = 0; i < RegMask.size(); ++i) { 764 for (SizeT i = 0; i < RegMask.size(); ++i) {
494 if (RegUses[i] > 0) 765 if (RegUses[i] > 0)
495 Free[i] = false; 766 Free[i] = false;
496 } 767 }
497 768
498 // Infer register preference and allowable overlap. Only form a 769 findRegisterPreference(Cur, RegMask);
499 // preference when the current Variable has an unambiguous "first" 770 filterFreeWithInactiveRanges(Cur);
500 // definition. The preference is some source Variable of the
501 // defining instruction that either is assigned a register that is
502 // currently free, or that is assigned a register that is not free
503 // but overlap is allowed. Overlap is allowed when the Variable
504 // under consideration is single-definition, and its definition is
505 // a simple assignment - i.e., the register gets copied/aliased
506 // but is never modified. Furthermore, overlap is only allowed
507 // when preferred Variable definition instructions do not appear
508 // within the current Variable's live range.
509 Variable *Prefer = nullptr;
510 int32_t PreferReg = Variable::NoRegister;
511 bool AllowOverlap = false;
512 if (FindPreference) {
513 if (const Inst *DefInst = VMetadata->getFirstDefinition(Cur)) {
514 assert(DefInst->getDest() == Cur);
515 bool IsAssign = DefInst->isSimpleAssign();
516 bool IsSingleDef = !VMetadata->isMultiDef(Cur);
517 for (SizeT i = 0; i < DefInst->getSrcSize(); ++i) {
518 // TODO(stichnot): Iterate through the actual Variables of the
519 // instruction, not just the source operands. This could
520 // capture Load instructions, including address mode
521 // optimization, for Prefer (but not for AllowOverlap).
522 if (Variable *SrcVar = llvm::dyn_cast<Variable>(DefInst->getSrc(i))) {
523 int32_t SrcReg = SrcVar->getRegNumTmp();
524 // Only consider source variables that have (so far) been
525 // assigned a register. That register must be one in the
526 // RegMask set, e.g. don't try to prefer the stack pointer
527 // as a result of the stacksave intrinsic.
528 if (SrcVar->hasRegTmp() && RegMask[SrcReg]) {
529 if (FindOverlap && !Free[SrcReg]) {
530 // Don't bother trying to enable AllowOverlap if the
531 // register is already free.
532 AllowOverlap =
533 IsSingleDef && IsAssign && !overlapsDefs(Func, Cur, SrcVar);
534 }
535 if (AllowOverlap || Free[SrcReg]) {
536 Prefer = SrcVar;
537 PreferReg = SrcReg;
538 }
539 }
540 }
541 }
542 if (Verbose && Prefer) {
543 Ostream &Str = Ctx->getStrDump();
544 Str << "Initial Prefer=";
545 Prefer->dump(Func);
546 Str << " R=" << PreferReg << " LIVE=" << Prefer->getLiveRange()
547 << " Overlap=" << AllowOverlap << "\n";
548 }
549 }
550 }
551
552 // Remove registers from the Free[] list where an Inactive range
553 // overlaps with the current range.
554 for (const Variable *Item : Inactive) {
555 if (Item->rangeOverlaps(Cur)) {
556 int32_t RegNum = Item->getRegNumTmp();
557 // Don't assert(Free[RegNum]) because in theory (though
558 // probably never in practice) there could be two inactive
559 // variables that were marked with AllowOverlap.
560 Free[RegNum] = false;
561 // Disable AllowOverlap if an Inactive variable, which is not
562 // Prefer, shares Prefer's register, and has a definition
563 // within Cur's live range.
564 if (AllowOverlap && Item != Prefer && RegNum == PreferReg &&
565 overlapsDefs(Func, Cur, Item)) {
566 AllowOverlap = false;
567 dumpDisableOverlap(Func, Item, "Inactive");
568 }
569 }
570 }
571 771
572 // Disable AllowOverlap if an Active variable, which is not 772 // Disable AllowOverlap if an Active variable, which is not
573 // Prefer, shares Prefer's register, and has a definition within 773 // Prefer, shares Prefer's register, and has a definition within
574 // Cur's live range. 774 // Cur's live range.
575 if (AllowOverlap) { 775 if (AllowOverlap) {
576 for (const Variable *Item : Active) { 776 for (const Variable *Item : Active) {
577 int32_t RegNum = Item->getRegNumTmp(); 777 int32_t RegNum = Item->getRegNumTmp();
578 if (Item != Prefer && RegNum == PreferReg && 778 if (Item != Prefer && RegNum == PreferReg &&
579 overlapsDefs(Func, Cur, Item)) { 779 overlapsDefs(Func, Cur, Item)) {
580 AllowOverlap = false; 780 AllowOverlap = false;
581 dumpDisableOverlap(Func, Item, "Active"); 781 dumpDisableOverlap(Func, Item, "Active");
582 } 782 }
583 } 783 }
584 } 784 }
585 785
586 llvm::SmallVector<RegWeight, REGS_SIZE> Weights(RegMask.size()); 786 Weights.resize(RegMask.size());
Jim Stichnoth 2015/08/24 15:08:30 It seems to me that Weights and PrecoloredUnhandle
ascull 2015/08/24 19:53:47 The resize must be in the loops .size() is used by
787 std::fill(Weights.begin(), Weights.end(), RegWeight());
587 788
588 // Remove registers from the Free[] list where an Unhandled 789 PrecoloredUnhandledMask.resize(RegMask.size());
589 // pre-colored range overlaps with the current range, and set those 790 PrecoloredUnhandledMask.reset();
590 // registers to infinite weight so that they aren't candidates for 791
591 // eviction. Cur->rangeEndsBefore(Item) is an early exit check 792 filterFreeWithPrecoloredRanges(Cur);
592 // that turns a guaranteed O(N^2) algorithm into expected linear
593 // complexity.
594 llvm::SmallBitVector PrecoloredUnhandledMask(RegMask.size());
595 // Note: PrecoloredUnhandledMask is only used for dumping.
596 for (Variable *Item : reverse_range(UnhandledPrecolored)) {
597 assert(Item->hasReg());
598 if (Cur->rangeEndsBefore(Item))
599 break;
600 if (Item->rangeOverlaps(Cur)) {
601 int32_t ItemReg = Item->getRegNum(); // Note: not getRegNumTmp()
602 Weights[ItemReg].setWeight(RegWeight::Inf);
603 Free[ItemReg] = false;
604 PrecoloredUnhandledMask[ItemReg] = true;
605 // Disable AllowOverlap if the preferred register is one of
606 // these pre-colored unhandled overlapping ranges.
607 if (AllowOverlap && ItemReg == PreferReg) {
608 AllowOverlap = false;
609 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled");
610 }
611 }
612 }
613 793
614 // Remove scratch registers from the Free[] list, and mark their 794 // Remove scratch registers from the Free[] list, and mark their
615 // Weights[] as infinite, if KillsRange overlaps Cur's live range. 795 // Weights[] as infinite, if KillsRange overlaps Cur's live range.
616 constexpr bool UseTrimmed = true; 796 constexpr bool UseTrimmed = true;
617 if (Cur->getLiveRange().overlaps(KillsRange, UseTrimmed)) { 797 if (Cur->getLiveRange().overlaps(KillsRange, UseTrimmed)) {
618 Free.reset(KillsMask); 798 Free.reset(KillsMask);
619 for (int i = KillsMask.find_first(); i != -1; 799 for (int i = KillsMask.find_first(); i != -1;
620 i = KillsMask.find_next(i)) { 800 i = KillsMask.find_next(i)) {
621 Weights[i].setWeight(RegWeight::Inf); 801 Weights[i].setWeight(RegWeight::Inf);
622 if (PreferReg == i) 802 if (PreferReg == i)
623 AllowOverlap = false; 803 AllowOverlap = false;
624 } 804 }
625 } 805 }
626 806
627 // Print info about physical register availability. 807 // Print info about physical register availability.
628 if (Verbose) { 808 if (Verbose) {
629 Ostream &Str = Ctx->getStrDump(); 809 Ostream &Str = Ctx->getStrDump();
630 for (SizeT i = 0; i < RegMask.size(); ++i) { 810 for (SizeT i = 0; i < RegMask.size(); ++i) {
631 if (RegMask[i]) { 811 if (RegMask[i]) {
632 Str << Func->getTarget()->getRegName(i, IceType_i32) 812 Str << Func->getTarget()->getRegName(i, IceType_i32)
633 << "(U=" << RegUses[i] << ",F=" << Free[i] 813 << "(U=" << RegUses[i] << ",F=" << Free[i]
634 << ",P=" << PrecoloredUnhandledMask[i] << ") "; 814 << ",P=" << PrecoloredUnhandledMask[i] << ") ";
635 } 815 }
636 } 816 }
637 Str << "\n"; 817 Str << "\n";
638 } 818 }
639 819
640 if (Prefer && (AllowOverlap || Free[PreferReg])) { 820 if (Prefer && (AllowOverlap || Free[PreferReg])) {
641 // First choice: a preferred register that is either free or is 821 // First choice: a preferred register that is either free or is allowed
642 // allowed to overlap with its linked variable. 822 // to overlap with its linked variable.
643 Cur->setRegNumTmp(PreferReg); 823 allocatePreferedRegister(Cur);
644 if (Verbose) {
645 Ostream &Str = Ctx->getStrDump();
646 Str << "Preferring ";
647 dumpLiveRange(Cur, Func);
648 Str << "\n";
649 }
650 assert(RegUses[PreferReg] >= 0);
651 ++RegUses[PreferReg];
652 Active.push_back(Cur);
653 } else if (Free.any()) { 824 } else if (Free.any()) {
654 // Second choice: any free register. TODO: After explicit 825 // Second choice: any free register. TODO: After explicit affinity is
Jim Stichnoth 2015/08/24 15:08:30 I think this TODO should be removed.
ascull 2015/08/24 19:53:47 Done.
655 // affinity is considered, is there a strategy better than just 826 // considered, is there a strategy better than just picking the
656 // picking the lowest-numbered available register? 827 // lowest-numbered available register?
657 int32_t RegNum = Free.find_first(); 828 allocateFreeRegister(Cur);
658 Cur->setRegNumTmp(RegNum);
659 if (Verbose) {
660 Ostream &Str = Ctx->getStrDump();
661 Str << "Allocating ";
662 dumpLiveRange(Cur, Func);
663 Str << "\n";
664 }
665 assert(RegUses[RegNum] >= 0);
666 ++RegUses[RegNum];
667 Active.push_back(Cur);
668 } else { 829 } else {
669 // Fallback: there are no free registers, so we look for the 830 // Fallback: there are no free registers, so we look for the
670 // lowest-weight register and see if Cur has higher weight. 831 // lowest-weight register and see if Cur has higher weight.
671 // Check Active ranges. 832 handleNoFreeRegisters(Cur, RegMask);
672 for (const Variable *Item : Active) {
673 assert(Item->rangeOverlaps(Cur));
674 int32_t RegNum = Item->getRegNumTmp();
675 assert(Item->hasRegTmp());
676 Weights[RegNum].addWeight(Item->getLiveRange().getWeight());
677 }
678 // Same as above, but check Inactive ranges instead of Active.
679 for (const Variable *Item : Inactive) {
680 int32_t RegNum = Item->getRegNumTmp();
681 assert(Item->hasRegTmp());
682 if (Item->rangeOverlaps(Cur))
683 Weights[RegNum].addWeight(Item->getLiveRange().getWeight());
684 }
685
686 // All the weights are now calculated. Find the register with
687 // smallest weight.
688 int32_t MinWeightIndex = RegMask.find_first();
689 // MinWeightIndex must be valid because of the initial
690 // RegMask.any() test.
691 assert(MinWeightIndex >= 0);
692 for (SizeT i = MinWeightIndex + 1; i < Weights.size(); ++i) {
693 if (RegMask[i] && Weights[i] < Weights[MinWeightIndex])
694 MinWeightIndex = i;
695 }
696
697 if (Cur->getLiveRange().getWeight() <= Weights[MinWeightIndex]) {
698 // Cur doesn't have priority over any other live ranges, so
699 // don't allocate any register to it, and move it to the
700 // Handled state.
701 Handled.push_back(Cur);
702 if (Cur->getLiveRange().getWeight().isInf()) {
703 if (Kind == RAK_Phi)
704 addSpillFill(Cur, RegMask);
705 else
706 Func->setError("Unable to find a physical register for an "
707 "infinite-weight live range");
708 }
709 } else {
710 // Evict all live ranges in Active that register number
711 // MinWeightIndex is assigned to.
712 for (SizeT I = Active.size(); I > 0; --I) {
713 const SizeT Index = I - 1;
714 Variable *Item = Active[Index];
715 if (Item->getRegNumTmp() == MinWeightIndex) {
716 if (Verbose) {
717 Ostream &Str = Ctx->getStrDump();
718 Str << "Evicting ";
719 dumpLiveRange(Item, Func);
720 Str << "\n";
721 }
722 --RegUses[MinWeightIndex];
723 assert(RegUses[MinWeightIndex] >= 0);
724 Item->setRegNumTmp(Variable::NoRegister);
725 moveItem(Active, Index, Handled);
726 }
727 }
728 // Do the same for Inactive.
729 for (SizeT I = Inactive.size(); I > 0; --I) {
730 const SizeT Index = I - 1;
731 Variable *Item = Inactive[Index];
732 // Note: The Item->rangeOverlaps(Cur) clause is not part of the
733 // description of AssignMemLoc() in the original paper. But
734 // there doesn't seem to be any need to evict an inactive
735 // live range that doesn't overlap with the live range
736 // currently being considered. It's especially bad if we
737 // would end up evicting an infinite-weight but
738 // currently-inactive live range. The most common situation
739 // for this would be a scratch register kill set for call
740 // instructions.
741 if (Item->getRegNumTmp() == MinWeightIndex &&
742 Item->rangeOverlaps(Cur)) {
743 if (Verbose) {
744 Ostream &Str = Ctx->getStrDump();
745 Str << "Evicting ";
746 dumpLiveRange(Item, Func);
747 Str << "\n";
748 }
749 Item->setRegNumTmp(Variable::NoRegister);
750 moveItem(Inactive, Index, Handled);
751 }
752 }
753 // Assign the register to Cur.
754 Cur->setRegNumTmp(MinWeightIndex);
755 assert(RegUses[MinWeightIndex] >= 0);
756 ++RegUses[MinWeightIndex];
757 Active.push_back(Cur);
758 if (Verbose) {
759 Ostream &Str = Ctx->getStrDump();
760 Str << "Allocating ";
761 dumpLiveRange(Cur, Func);
762 Str << "\n";
763 }
764 }
765 } 833 }
766 dump(Func); 834 dump(Func);
767 } 835 }
836
768 // Move anything Active or Inactive to Handled for easier handling. 837 // Move anything Active or Inactive to Handled for easier handling.
769 for (Variable *I : Active) 838 Handled.insert(Handled.end(), Active.begin(), Active.end());
770 Handled.push_back(I);
771 Active.clear(); 839 Active.clear();
772 for (Variable *I : Inactive) 840 Handled.insert(Handled.end(), Inactive.begin(), Inactive.end());
773 Handled.push_back(I);
774 Inactive.clear(); 841 Inactive.clear();
775 dump(Func); 842 dump(Func);
776 843
777 llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters); 844 assignFinalRegisters(RegMaskFull, PreDefinedRegisters, Randomized);
778 if (Randomized) {
779 // Create a random number generator for regalloc randomization. Merge
780 // function's sequence and Kind value as the Salt. Because regAlloc()
781 // is called twice under O2, the second time with RAK_Phi, we check
782 // Kind == RAK_Phi to determine the lowest-order bit to make sure the
783 // Salt is different.
784 uint64_t Salt =
785 (Func->getSequenceNumber() << 1) ^ (Kind == RAK_Phi ? 0u : 1u);
786 Func->getTarget()->makeRandomRegisterPermutation(
787 Permutation, PreDefinedRegisters | ~RegMaskFull, Salt);
788 }
789
790 // Finish up by assigning RegNumTmp->RegNum (or a random permutation
791 // thereof) for each Variable.
792 for (Variable *Item : Handled) {
793 int32_t RegNum = Item->getRegNumTmp();
794 int32_t AssignedRegNum = RegNum;
795
796 if (Randomized && Item->hasRegTmp() && !Item->hasReg()) {
797 AssignedRegNum = Permutation[RegNum];
798 }
799 if (Verbose) {
800 Ostream &Str = Ctx->getStrDump();
801 if (!Item->hasRegTmp()) {
802 Str << "Not assigning ";
803 Item->dump(Func);
804 Str << "\n";
805 } else {
806 Str << (AssignedRegNum == Item->getRegNum() ? "Reassigning "
807 : "Assigning ")
808 << Func->getTarget()->getRegName(AssignedRegNum, IceType_i32)
809 << "(r" << AssignedRegNum << ") to ";
810 Item->dump(Func);
811 Str << "\n";
812 }
813 }
814 Item->setRegNum(AssignedRegNum);
815 }
816 845
817 // TODO: Consider running register allocation one more time, with 846 // TODO: Consider running register allocation one more time, with
818 // infinite registers, for two reasons. First, evicted live ranges 847 // infinite registers, for two reasons. First, evicted live ranges
819 // get a second chance for a register. Second, it allows coalescing 848 // get a second chance for a register. Second, it allows coalescing
820 // of stack slots. If there is no time budget for the second 849 // of stack slots. If there is no time budget for the second
821 // register allocation run, each unallocated variable just gets its 850 // register allocation run, each unallocated variable just gets its
822 // own slot. 851 // own slot.
823 // 852 //
824 // Another idea for coalescing stack slots is to initialize the 853 // Another idea for coalescing stack slots is to initialize the
825 // Unhandled list with just the unallocated variables, saving time 854 // Unhandled list with just the unallocated variables, saving time
(...skipping 29 matching lines...) Expand all
855 Str << "\n"; 884 Str << "\n";
856 } 885 }
857 Str << "++++++ Inactive:\n"; 886 Str << "++++++ Inactive:\n";
858 for (const Variable *Item : Inactive) { 887 for (const Variable *Item : Inactive) {
859 dumpLiveRange(Item, Func); 888 dumpLiveRange(Item, Func);
860 Str << "\n"; 889 Str << "\n";
861 } 890 }
862 } 891 }
863 892
864 } // end of namespace Ice 893 } // end of namespace Ice
OLDNEW
« src/IceRegAlloc.h ('K') | « src/IceRegAlloc.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698