Chromium Code Reviews| 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 |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |