| OLD | NEW |
| 1 //===- subzero/src/IceRegAlloc.cpp - Linear-scan implementation -----------===// | 1 //===- subzero/src/IceRegAlloc.cpp - Linear-scan implementation -----------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 char buf[30]; | 72 char buf[30]; |
| 73 snprintf(buf, llvm::array_lengthof(buf), "%2d", Var->getRegNumTmp()); | 73 snprintf(buf, llvm::array_lengthof(buf), "%2d", Var->getRegNumTmp()); |
| 74 Str << "R=" << buf << " V="; | 74 Str << "R=" << buf << " V="; |
| 75 Var->dump(Func); | 75 Var->dump(Func); |
| 76 Str << " Range=" << Var->getLiveRange(); | 76 Str << " Range=" << Var->getLiveRange(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 } // end of anonymous namespace | 79 } // end of anonymous namespace |
| 80 | 80 |
| 81 LinearScan::LinearScan(Cfg *Func) | 81 LinearScan::LinearScan(Cfg *Func) |
| 82 : Func(Func), Ctx(Func->getContext()), | 82 : Func(Func), Ctx(Func->getContext()), Target(Func->getTarget()), |
| 83 Verbose(BuildDefs::dump() && Func->isVerbose(IceV_LinearScan)) {} | 83 Verbose(BuildDefs::dump() && Func->isVerbose(IceV_LinearScan)) {} |
| 84 | 84 |
| 85 // Prepare for full register allocation of all variables. We depend on | 85 // Prepare for full register allocation of all variables. We depend on |
| 86 // liveness analysis to have calculated live ranges. | 86 // liveness analysis to have calculated live ranges. |
| 87 void LinearScan::initForGlobal() { | 87 void LinearScan::initForGlobal() { |
| 88 TimerMarker T(TimerStack::TT_initUnhandled, Func); | 88 TimerMarker T(TimerStack::TT_initUnhandled, Func); |
| 89 FindPreference = true; | 89 FindPreference = true; |
| 90 // For full register allocation, normally we want to enable FindOverlap | 90 // For full register allocation, normally we want to enable FindOverlap |
| 91 // (meaning we look for opportunities for two overlapping live ranges to | 91 // (meaning we look for opportunities for two overlapping live ranges to |
| 92 // safely share the same register). However, we disable it for phi-lowering | 92 // safely share the same register). However, we disable it for phi-lowering |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 } | 218 } |
| 219 | 219 |
| 220 void LinearScan::init(RegAllocKind Kind) { | 220 void LinearScan::init(RegAllocKind Kind) { |
| 221 this->Kind = Kind; | 221 this->Kind = Kind; |
| 222 Unhandled.clear(); | 222 Unhandled.clear(); |
| 223 UnhandledPrecolored.clear(); | 223 UnhandledPrecolored.clear(); |
| 224 Handled.clear(); | 224 Handled.clear(); |
| 225 Inactive.clear(); | 225 Inactive.clear(); |
| 226 Active.clear(); | 226 Active.clear(); |
| 227 | 227 |
| 228 SizeT NumRegs = Target->getNumRegisters(); |
| 229 RegAliases.resize(NumRegs); |
| 230 for (SizeT Reg = 0; Reg < NumRegs; ++Reg) { |
| 231 RegAliases[Reg] = &Target->getAliasesForRegister(Reg); |
| 232 } |
| 233 |
| 228 switch (Kind) { | 234 switch (Kind) { |
| 229 case RAK_Unknown: | 235 case RAK_Unknown: |
| 230 llvm::report_fatal_error("Invalid RAK_Unknown"); | 236 llvm::report_fatal_error("Invalid RAK_Unknown"); |
| 231 break; | 237 break; |
| 232 case RAK_Global: | 238 case RAK_Global: |
| 233 case RAK_Phi: | 239 case RAK_Phi: |
| 234 initForGlobal(); | 240 initForGlobal(); |
| 235 break; | 241 break; |
| 236 case RAK_InfOnly: | 242 case RAK_InfOnly: |
| 237 initForInfOnly(); | 243 initForInfOnly(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 I != E && (SpillPoint == E || FillPoint == E); ++I) { | 294 I != E && (SpillPoint == E || FillPoint == E); ++I) { |
| 289 if (I->getNumber() == Start) | 295 if (I->getNumber() == Start) |
| 290 SpillPoint = I; | 296 SpillPoint = I; |
| 291 if (I->getNumber() == End) | 297 if (I->getNumber() == End) |
| 292 FillPoint = I; | 298 FillPoint = I; |
| 293 if (SpillPoint != E) { | 299 if (SpillPoint != E) { |
| 294 // Remove from RegMask any physical registers referenced during Cur's live | 300 // Remove from RegMask any physical registers referenced during Cur's live |
| 295 // range. Start looking after SpillPoint gets set, i.e. once Cur's live | 301 // range. Start looking after SpillPoint gets set, i.e. once Cur's live |
| 296 // range begins. | 302 // range begins. |
| 297 FOREACH_VAR_IN_INST(Var, *I) { | 303 FOREACH_VAR_IN_INST(Var, *I) { |
| 298 if (Var->hasRegTmp()) | 304 if (!Var->hasRegTmp()) |
| 299 Iter.RegMask[Var->getRegNumTmp()] = false; | 305 continue; |
| 306 const llvm::SmallBitVector &Aliases = *RegAliases[Var->getRegNumTmp()]; |
| 307 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 308 RegAlias = Aliases.find_next(RegAlias)) { |
| 309 Iter.RegMask[RegAlias] = false; |
| 310 } |
| 300 } | 311 } |
| 301 } | 312 } |
| 302 } | 313 } |
| 303 assert(SpillPoint != Insts.end()); | 314 assert(SpillPoint != Insts.end()); |
| 304 assert(FillPoint != Insts.end()); | 315 assert(FillPoint != Insts.end()); |
| 305 ++FillPoint; | 316 ++FillPoint; |
| 306 // TODO(stichnot): Randomize instead of find_first(). | 317 // TODO(stichnot): Randomize instead of find_first(). |
| 307 int32_t RegNum = Iter.RegMask.find_first(); | 318 int32_t RegNum = Iter.RegMask.find_first(); |
| 308 assert(RegNum != -1); | 319 assert(RegNum != -1); |
| 309 Iter.Cur->setRegNumTmp(RegNum); | 320 Iter.Cur->setRegNumTmp(RegNum); |
| 310 TargetLowering *Target = Func->getTarget(); | |
| 311 Variable *Preg = Target->getPhysicalRegister(RegNum, Iter.Cur->getType()); | 321 Variable *Preg = Target->getPhysicalRegister(RegNum, Iter.Cur->getType()); |
| 312 // TODO(stichnot): Add SpillLoc to VariablesMetadata tracking so that SpillLoc | 322 // TODO(stichnot): Add SpillLoc to VariablesMetadata tracking so that SpillLoc |
| 313 // is correctly identified as !isMultiBlock(), reducing stack frame size. | 323 // is correctly identified as !isMultiBlock(), reducing stack frame size. |
| 314 Variable *SpillLoc = Func->makeVariable(Iter.Cur->getType()); | 324 Variable *SpillLoc = Func->makeVariable(Iter.Cur->getType()); |
| 315 // Add "reg=FakeDef;spill=reg" before SpillPoint | 325 // Add "reg=FakeDef;spill=reg" before SpillPoint |
| 316 Target->lowerInst(Node, SpillPoint, InstFakeDef::create(Func, Preg)); | 326 Target->lowerInst(Node, SpillPoint, InstFakeDef::create(Func, Preg)); |
| 317 Target->lowerInst(Node, SpillPoint, InstAssign::create(Func, SpillLoc, Preg)); | 327 Target->lowerInst(Node, SpillPoint, InstAssign::create(Func, SpillLoc, Preg)); |
| 318 // add "reg=spill;FakeUse(reg)" before FillPoint | 328 // add "reg=spill;FakeUse(reg)" before FillPoint |
| 319 Target->lowerInst(Node, FillPoint, InstAssign::create(Func, Preg, SpillLoc)); | 329 Target->lowerInst(Node, FillPoint, InstAssign::create(Func, Preg, SpillLoc)); |
| 320 Target->lowerInst(Node, FillPoint, InstFakeUse::create(Func, Preg)); | 330 Target->lowerInst(Node, FillPoint, InstFakeUse::create(Func, Preg)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 333 Moved = true; | 343 Moved = true; |
| 334 } else if (!Item->rangeOverlapsStart(Cur)) { | 344 } else if (!Item->rangeOverlapsStart(Cur)) { |
| 335 // Move Item from Active to Inactive list. | 345 // Move Item from Active to Inactive list. |
| 336 dumpLiveRangeTrace("Inactivating ", Cur); | 346 dumpLiveRangeTrace("Inactivating ", Cur); |
| 337 moveItem(Active, Index, Inactive); | 347 moveItem(Active, Index, Inactive); |
| 338 Moved = true; | 348 Moved = true; |
| 339 } | 349 } |
| 340 if (Moved) { | 350 if (Moved) { |
| 341 // Decrement Item from RegUses[]. | 351 // Decrement Item from RegUses[]. |
| 342 assert(Item->hasRegTmp()); | 352 assert(Item->hasRegTmp()); |
| 343 int32_t RegNum = Item->getRegNumTmp(); | 353 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
| 344 --RegUses[RegNum]; | 354 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 345 assert(RegUses[RegNum] >= 0); | 355 RegAlias = Aliases.find_next(RegAlias)) { |
| 356 --RegUses[RegAlias]; |
| 357 assert(RegUses[RegAlias] >= 0); |
| 358 } |
| 346 } | 359 } |
| 347 } | 360 } |
| 348 } | 361 } |
| 349 | 362 |
| 350 void LinearScan::handleInactiveRangeExpiredOrReactivated(const Variable *Cur) { | 363 void LinearScan::handleInactiveRangeExpiredOrReactivated(const Variable *Cur) { |
| 351 for (SizeT I = Inactive.size(); I > 0; --I) { | 364 for (SizeT I = Inactive.size(); I > 0; --I) { |
| 352 const SizeT Index = I - 1; | 365 const SizeT Index = I - 1; |
| 353 Variable *Item = Inactive[Index]; | 366 Variable *Item = Inactive[Index]; |
| 354 Item->trimLiveRange(Cur->getLiveRange().getStart()); | 367 Item->trimLiveRange(Cur->getLiveRange().getStart()); |
| 355 if (Item->rangeEndsBefore(Cur)) { | 368 if (Item->rangeEndsBefore(Cur)) { |
| 356 // Move Item from Inactive to Handled list. | 369 // Move Item from Inactive to Handled list. |
| 357 dumpLiveRangeTrace("Expiring ", Cur); | 370 dumpLiveRangeTrace("Expiring ", Cur); |
| 358 moveItem(Inactive, Index, Handled); | 371 moveItem(Inactive, Index, Handled); |
| 359 } else if (Item->rangeOverlapsStart(Cur)) { | 372 } else if (Item->rangeOverlapsStart(Cur)) { |
| 360 // Move Item from Inactive to Active list. | 373 // Move Item from Inactive to Active list. |
| 361 dumpLiveRangeTrace("Reactivating ", Cur); | 374 dumpLiveRangeTrace("Reactivating ", Cur); |
| 362 moveItem(Inactive, Index, Active); | 375 moveItem(Inactive, Index, Active); |
| 363 // Increment Item in RegUses[]. | 376 // Increment Item in RegUses[]. |
| 364 assert(Item->hasRegTmp()); | 377 assert(Item->hasRegTmp()); |
| 365 int32_t RegNum = Item->getRegNumTmp(); | 378 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
| 366 assert(RegUses[RegNum] >= 0); | 379 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 367 ++RegUses[RegNum]; | 380 RegAlias = Aliases.find_next(RegAlias)) { |
| 381 assert(RegUses[RegAlias] >= 0); |
| 382 ++RegUses[RegAlias]; |
| 383 } |
| 368 } | 384 } |
| 369 } | 385 } |
| 370 } | 386 } |
| 371 | 387 |
| 372 // Infer register preference and allowable overlap. Only form a preference when | 388 // Infer register preference and allowable overlap. Only form a preference when |
| 373 // the current Variable has an unambiguous "first" definition. The preference | 389 // the current Variable has an unambiguous "first" definition. The preference |
| 374 // is some source Variable of the defining instruction that either is assigned | 390 // is some source Variable of the defining instruction that either is assigned |
| 375 // a register that is currently free, or that is assigned a register that is | 391 // a register that is currently free, or that is assigned a register that is |
| 376 // not free but overlap is allowed. Overlap is allowed when the Variable under | 392 // not free but overlap is allowed. Overlap is allowed when the Variable under |
| 377 // consideration is single-definition, and its definition is a simple | 393 // consideration is single-definition, and its definition is a simple |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 << " Overlap=" << Iter.AllowOverlap << "\n"; | 439 << " Overlap=" << Iter.AllowOverlap << "\n"; |
| 424 } | 440 } |
| 425 } | 441 } |
| 426 } | 442 } |
| 427 } | 443 } |
| 428 | 444 |
| 429 // Remove registers from the Free[] list where an Inactive range overlaps with | 445 // Remove registers from the Free[] list where an Inactive range overlaps with |
| 430 // the current range. | 446 // the current range. |
| 431 void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) { | 447 void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) { |
| 432 for (const Variable *Item : Inactive) { | 448 for (const Variable *Item : Inactive) { |
| 433 if (Item->rangeOverlaps(Iter.Cur)) { | 449 if (!Item->rangeOverlaps(Iter.Cur)) |
| 434 int32_t RegNum = Item->getRegNumTmp(); | 450 continue; |
| 451 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
| 452 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 453 RegAlias = Aliases.find_next(RegAlias)) { |
| 435 // Don't assert(Free[RegNum]) because in theory (though probably never in | 454 // Don't assert(Free[RegNum]) because in theory (though probably never in |
| 436 // practice) there could be two inactive variables that were marked with | 455 // practice) there could be two inactive variables that were marked with |
| 437 // AllowOverlap. | 456 // AllowOverlap. |
| 438 Iter.Free[RegNum] = false; | 457 Iter.Free[RegAlias] = false; |
| 439 // Disable AllowOverlap if an Inactive variable, which is not Prefer, | 458 // Disable AllowOverlap if an Inactive variable, which is not Prefer, |
| 440 // shares Prefer's register, and has a definition within Cur's live | 459 // shares Prefer's register, and has a definition within Cur's live |
| 441 // range. | 460 // range. |
| 442 if (Iter.AllowOverlap && Item != Iter.Prefer && | 461 if (Iter.AllowOverlap && Item != Iter.Prefer && |
| 443 RegNum == Iter.PreferReg && overlapsDefs(Func, Iter.Cur, Item)) { | 462 RegAlias == Iter.PreferReg && overlapsDefs(Func, Iter.Cur, Item)) { |
| 444 Iter.AllowOverlap = false; | 463 Iter.AllowOverlap = false; |
| 445 dumpDisableOverlap(Func, Item, "Inactive"); | 464 dumpDisableOverlap(Func, Item, "Inactive"); |
| 446 } | 465 } |
| 447 } | 466 } |
| 448 } | 467 } |
| 449 } | 468 } |
| 450 | 469 |
| 451 // Remove registers from the Free[] list where an Unhandled pre-colored range | 470 // Remove registers from the Free[] list where an Unhandled pre-colored range |
| 452 // overlaps with the current range, and set those registers to infinite weight | 471 // overlaps with the current range, and set those registers to infinite weight |
| 453 // so that they aren't candidates for eviction. Cur->rangeEndsBefore(Item) is | 472 // so that they aren't candidates for eviction. Cur->rangeEndsBefore(Item) is |
| 454 // an early exit check that turns a guaranteed O(N^2) algorithm into expected | 473 // an early exit check that turns a guaranteed O(N^2) algorithm into expected |
| 455 // linear complexity. | 474 // linear complexity. |
| 456 void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) { | 475 void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) { |
| 457 for (Variable *Item : reverse_range(UnhandledPrecolored)) { | 476 for (Variable *Item : reverse_range(UnhandledPrecolored)) { |
| 458 assert(Item->hasReg()); | 477 assert(Item->hasReg()); |
| 459 if (Iter.Cur->rangeEndsBefore(Item)) | 478 if (Iter.Cur->rangeEndsBefore(Item)) |
| 460 break; | 479 break; |
| 461 if (Item->rangeOverlaps(Iter.Cur)) { | 480 if (Item->rangeOverlaps(Iter.Cur)) { |
| 462 int32_t ItemReg = Item->getRegNum(); // Note: not getRegNumTmp() | 481 const llvm::SmallBitVector &Aliases = |
| 463 Iter.Weights[ItemReg].setWeight(RegWeight::Inf); | 482 *RegAliases[Item->getRegNum()]; // Note: not getRegNumTmp() |
| 464 Iter.Free[ItemReg] = false; | 483 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 465 Iter.PrecoloredUnhandledMask[ItemReg] = true; | 484 RegAlias = Aliases.find_next(RegAlias)) { |
| 466 // Disable Iter.AllowOverlap if the preferred register is one of these | 485 Iter.Weights[RegAlias].setWeight(RegWeight::Inf); |
| 467 // pre-colored unhandled overlapping ranges. | 486 Iter.Free[RegAlias] = false; |
| 468 if (Iter.AllowOverlap && ItemReg == Iter.PreferReg) { | 487 Iter.PrecoloredUnhandledMask[RegAlias] = true; |
| 469 Iter.AllowOverlap = false; | 488 // Disable Iter.AllowOverlap if the preferred register is one of these |
| 470 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled"); | 489 // pre-colored unhandled overlapping ranges. |
| 490 if (Iter.AllowOverlap && RegAlias == Iter.PreferReg) { |
| 491 Iter.AllowOverlap = false; |
| 492 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled"); |
| 493 } |
| 471 } | 494 } |
| 472 } | 495 } |
| 473 } | 496 } |
| 474 } | 497 } |
| 475 | 498 |
| 476 void LinearScan::allocatePrecoloredRegister(Variable *Cur) { | 499 void LinearScan::allocatePrecoloredRegister(Variable *Cur) { |
| 477 int32_t RegNum = Cur->getRegNum(); | 500 int32_t RegNum = Cur->getRegNum(); |
| 478 // RegNumTmp should have already been set above. | 501 // RegNumTmp should have already been set above. |
| 479 assert(Cur->getRegNumTmp() == RegNum); | 502 assert(Cur->getRegNumTmp() == RegNum); |
| 480 dumpLiveRangeTrace("Precoloring ", Cur); | 503 dumpLiveRangeTrace("Precoloring ", Cur); |
| 481 Active.push_back(Cur); | 504 Active.push_back(Cur); |
| 482 assert(RegUses[RegNum] >= 0); | 505 const llvm::SmallBitVector &Aliases = *RegAliases[RegNum]; |
| 483 ++RegUses[RegNum]; | 506 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 507 RegAlias = Aliases.find_next(RegAlias)) { |
| 508 assert(RegUses[RegAlias] >= 0); |
| 509 ++RegUses[RegAlias]; |
| 510 } |
| 484 assert(!UnhandledPrecolored.empty()); | 511 assert(!UnhandledPrecolored.empty()); |
| 485 assert(UnhandledPrecolored.back() == Cur); | 512 assert(UnhandledPrecolored.back() == Cur); |
| 486 UnhandledPrecolored.pop_back(); | 513 UnhandledPrecolored.pop_back(); |
| 487 } | 514 } |
| 488 | 515 |
| 489 void LinearScan::allocatePreferredRegister(IterationState &Iter) { | 516 void LinearScan::allocatePreferredRegister(IterationState &Iter) { |
| 490 Iter.Cur->setRegNumTmp(Iter.PreferReg); | 517 Iter.Cur->setRegNumTmp(Iter.PreferReg); |
| 491 dumpLiveRangeTrace("Preferring ", Iter.Cur); | 518 dumpLiveRangeTrace("Preferring ", Iter.Cur); |
| 492 assert(RegUses[Iter.PreferReg] >= 0); | 519 const llvm::SmallBitVector &Aliases = *RegAliases[Iter.PreferReg]; |
| 493 ++RegUses[Iter.PreferReg]; | 520 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 521 RegAlias = Aliases.find_next(RegAlias)) { |
| 522 assert(RegUses[RegAlias] >= 0); |
| 523 ++RegUses[RegAlias]; |
| 524 } |
| 494 Active.push_back(Iter.Cur); | 525 Active.push_back(Iter.Cur); |
| 495 } | 526 } |
| 496 | 527 |
| 497 void LinearScan::allocateFreeRegister(IterationState &Iter) { | 528 void LinearScan::allocateFreeRegister(IterationState &Iter) { |
| 498 int32_t RegNum = Iter.Free.find_first(); | 529 int32_t RegNum = Iter.Free.find_first(); |
| 499 Iter.Cur->setRegNumTmp(RegNum); | 530 Iter.Cur->setRegNumTmp(RegNum); |
| 500 dumpLiveRangeTrace("Allocating ", Iter.Cur); | 531 dumpLiveRangeTrace("Allocating ", Iter.Cur); |
| 501 assert(RegUses[RegNum] >= 0); | 532 const llvm::SmallBitVector &Aliases = *RegAliases[RegNum]; |
| 502 ++RegUses[RegNum]; | 533 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 534 RegAlias = Aliases.find_next(RegAlias)) { |
| 535 assert(RegUses[RegAlias] >= 0); |
| 536 ++RegUses[RegAlias]; |
| 537 } |
| 503 Active.push_back(Iter.Cur); | 538 Active.push_back(Iter.Cur); |
| 504 } | 539 } |
| 505 | 540 |
| 506 void LinearScan::handleNoFreeRegisters(IterationState &Iter) { | 541 void LinearScan::handleNoFreeRegisters(IterationState &Iter) { |
| 507 // Check Active ranges. | 542 // Check Active ranges. |
| 508 for (const Variable *Item : Active) { | 543 for (const Variable *Item : Active) { |
| 509 assert(Item->rangeOverlaps(Iter.Cur)); | 544 assert(Item->rangeOverlaps(Iter.Cur)); |
| 510 int32_t RegNum = Item->getRegNumTmp(); | |
| 511 assert(Item->hasRegTmp()); | 545 assert(Item->hasRegTmp()); |
| 512 Iter.Weights[RegNum].addWeight(Item->getWeight(Func)); | 546 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
| 547 // We add the Item's weight to each alias/subregister to represent that, |
| 548 // should we decide to pick any of them, then we would incur that many |
| 549 // memory accesses. |
| 550 RegWeight W = Item->getWeight(Func); |
| 551 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 552 RegAlias = Aliases.find_next(RegAlias)) { |
| 553 Iter.Weights[RegAlias].addWeight(W); |
| 554 } |
| 513 } | 555 } |
| 514 // Same as above, but check Inactive ranges instead of Active. | 556 // Same as above, but check Inactive ranges instead of Active. |
| 515 for (const Variable *Item : Inactive) { | 557 for (const Variable *Item : Inactive) { |
| 516 int32_t RegNum = Item->getRegNumTmp(); | 558 if (!Item->rangeOverlaps(Iter.Cur)) |
| 559 continue; |
| 517 assert(Item->hasRegTmp()); | 560 assert(Item->hasRegTmp()); |
| 518 if (Item->rangeOverlaps(Iter.Cur)) | 561 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
| 519 Iter.Weights[RegNum].addWeight(Item->getWeight(Func)); | 562 RegWeight W = Item->getWeight(Func); |
| 563 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 564 RegAlias = Aliases.find_next(RegAlias)) { |
| 565 Iter.Weights[RegAlias].addWeight(W); |
| 566 } |
| 520 } | 567 } |
| 521 | 568 |
| 522 // All the weights are now calculated. Find the register with smallest | 569 // All the weights are now calculated. Find the register with smallest |
| 523 // weight. | 570 // weight. |
| 524 int32_t MinWeightIndex = Iter.RegMask.find_first(); | 571 int32_t MinWeightIndex = Iter.RegMask.find_first(); |
| 525 // MinWeightIndex must be valid because of the initial RegMask.any() test. | 572 // MinWeightIndex must be valid because of the initial RegMask.any() test. |
| 526 assert(MinWeightIndex >= 0); | 573 assert(MinWeightIndex >= 0); |
| 527 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) { | 574 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) { |
| 528 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex]) | 575 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex]) |
| 529 MinWeightIndex = i; | 576 MinWeightIndex = i; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 541 "infinite-weight live range"); | 588 "infinite-weight live range"); |
| 542 } | 589 } |
| 543 } else { | 590 } else { |
| 544 // Evict all live ranges in Active that register number MinWeightIndex is | 591 // Evict all live ranges in Active that register number MinWeightIndex is |
| 545 // assigned to. | 592 // assigned to. |
| 546 for (SizeT I = Active.size(); I > 0; --I) { | 593 for (SizeT I = Active.size(); I > 0; --I) { |
| 547 const SizeT Index = I - 1; | 594 const SizeT Index = I - 1; |
| 548 Variable *Item = Active[Index]; | 595 Variable *Item = Active[Index]; |
| 549 if (Item->getRegNumTmp() == MinWeightIndex) { | 596 if (Item->getRegNumTmp() == MinWeightIndex) { |
| 550 dumpLiveRangeTrace("Evicting ", Item); | 597 dumpLiveRangeTrace("Evicting ", Item); |
| 551 --RegUses[MinWeightIndex]; | 598 const llvm::SmallBitVector &Aliases = *RegAliases[MinWeightIndex]; |
| 552 assert(RegUses[MinWeightIndex] >= 0); | 599 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 600 RegAlias = Aliases.find_next(RegAlias)) { |
| 601 --RegUses[RegAlias]; |
| 602 assert(RegUses[RegAlias] >= 0); |
| 603 } |
| 553 Item->setRegNumTmp(Variable::NoRegister); | 604 Item->setRegNumTmp(Variable::NoRegister); |
| 554 moveItem(Active, Index, Handled); | 605 moveItem(Active, Index, Handled); |
| 555 } | 606 } |
| 556 } | 607 } |
| 557 // Do the same for Inactive. | 608 // Do the same for Inactive. |
| 558 for (SizeT I = Inactive.size(); I > 0; --I) { | 609 for (SizeT I = Inactive.size(); I > 0; --I) { |
| 559 const SizeT Index = I - 1; | 610 const SizeT Index = I - 1; |
| 560 Variable *Item = Inactive[Index]; | 611 Variable *Item = Inactive[Index]; |
| 561 // Note: The Item->rangeOverlaps(Cur) clause is not part of the | 612 // Note: The Item->rangeOverlaps(Cur) clause is not part of the |
| 562 // description of AssignMemLoc() in the original paper. But there | 613 // description of AssignMemLoc() in the original paper. But there |
| 563 // doesn't seem to be any need to evict an inactive live range that | 614 // doesn't seem to be any need to evict an inactive live range that |
| 564 // doesn't overlap with the live range currently being considered. It's | 615 // doesn't overlap with the live range currently being considered. It's |
| 565 // especially bad if we would end up evicting an infinite-weight but | 616 // especially bad if we would end up evicting an infinite-weight but |
| 566 // currently-inactive live range. The most common situation for this | 617 // currently-inactive live range. The most common situation for this |
| 567 // would be a scratch register kill set for call instructions. | 618 // would be a scratch register kill set for call instructions. |
| 568 if (Item->getRegNumTmp() == MinWeightIndex && | 619 if (Item->getRegNumTmp() == MinWeightIndex && |
| 569 Item->rangeOverlaps(Iter.Cur)) { | 620 Item->rangeOverlaps(Iter.Cur)) { |
| 570 dumpLiveRangeTrace("Evicting ", Item); | 621 dumpLiveRangeTrace("Evicting ", Item); |
| 571 Item->setRegNumTmp(Variable::NoRegister); | 622 Item->setRegNumTmp(Variable::NoRegister); |
| 572 moveItem(Inactive, Index, Handled); | 623 moveItem(Inactive, Index, Handled); |
| 573 } | 624 } |
| 574 } | 625 } |
| 575 // Assign the register to Cur. | 626 // Assign the register to Cur. |
| 576 Iter.Cur->setRegNumTmp(MinWeightIndex); | 627 Iter.Cur->setRegNumTmp(MinWeightIndex); |
| 577 assert(RegUses[MinWeightIndex] >= 0); | 628 const llvm::SmallBitVector &Aliases = *RegAliases[MinWeightIndex]; |
| 578 ++RegUses[MinWeightIndex]; | 629 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 630 RegAlias = Aliases.find_next(RegAlias)) { |
| 631 assert(RegUses[RegAlias] >= 0); |
| 632 ++RegUses[RegAlias]; |
| 633 } |
| 579 Active.push_back(Iter.Cur); | 634 Active.push_back(Iter.Cur); |
| 580 dumpLiveRangeTrace("Allocating ", Iter.Cur); | 635 dumpLiveRangeTrace("Allocating ", Iter.Cur); |
| 581 } | 636 } |
| 582 } | 637 } |
| 583 | 638 |
| 584 void LinearScan::assignFinalRegisters( | 639 void LinearScan::assignFinalRegisters( |
| 585 const llvm::SmallBitVector &RegMaskFull, | 640 const llvm::SmallBitVector &RegMaskFull, |
| 586 const llvm::SmallBitVector &PreDefinedRegisters, bool Randomized) { | 641 const llvm::SmallBitVector &PreDefinedRegisters, bool Randomized) { |
| 587 const size_t NumRegisters = RegMaskFull.size(); | 642 const size_t NumRegisters = RegMaskFull.size(); |
| 588 llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters); | 643 llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters); |
| 589 if (Randomized) { | 644 if (Randomized) { |
| 590 // Create a random number generator for regalloc randomization. Merge | 645 // Create a random number generator for regalloc randomization. Merge |
| 591 // function's sequence and Kind value as the Salt. Because regAlloc() is | 646 // function's sequence and Kind value as the Salt. Because regAlloc() is |
| 592 // called twice under O2, the second time with RAK_Phi, we check | 647 // called twice under O2, the second time with RAK_Phi, we check |
| 593 // Kind == RAK_Phi to determine the lowest-order bit to make sure the Salt | 648 // Kind == RAK_Phi to determine the lowest-order bit to make sure the Salt |
| 594 // is different. | 649 // is different. |
| 595 uint64_t Salt = | 650 uint64_t Salt = |
| 596 (Func->getSequenceNumber() << 1) ^ (Kind == RAK_Phi ? 0u : 1u); | 651 (Func->getSequenceNumber() << 1) ^ (Kind == RAK_Phi ? 0u : 1u); |
| 597 Func->getTarget()->makeRandomRegisterPermutation( | 652 Target->makeRandomRegisterPermutation( |
| 598 Permutation, PreDefinedRegisters | ~RegMaskFull, Salt); | 653 Permutation, PreDefinedRegisters | ~RegMaskFull, Salt); |
| 599 } | 654 } |
| 600 | 655 |
| 601 // Finish up by setting RegNum = RegNumTmp (or a random permutation thereof) | 656 // Finish up by setting RegNum = RegNumTmp (or a random permutation thereof) |
| 602 // for each Variable. | 657 // for each Variable. |
| 603 for (Variable *Item : Handled) { | 658 for (Variable *Item : Handled) { |
| 604 int32_t RegNum = Item->getRegNumTmp(); | 659 int32_t RegNum = Item->getRegNumTmp(); |
| 605 int32_t AssignedRegNum = RegNum; | 660 int32_t AssignedRegNum = RegNum; |
| 606 | 661 |
| 607 if (Randomized && Item->hasRegTmp() && !Item->hasReg()) { | 662 if (Randomized && Item->hasRegTmp() && !Item->hasReg()) { |
| 608 AssignedRegNum = Permutation[RegNum]; | 663 AssignedRegNum = Permutation[RegNum]; |
| 609 } | 664 } |
| 610 if (Verbose) { | 665 if (Verbose) { |
| 611 Ostream &Str = Ctx->getStrDump(); | 666 Ostream &Str = Ctx->getStrDump(); |
| 612 if (!Item->hasRegTmp()) { | 667 if (!Item->hasRegTmp()) { |
| 613 Str << "Not assigning "; | 668 Str << "Not assigning "; |
| 614 Item->dump(Func); | 669 Item->dump(Func); |
| 615 Str << "\n"; | 670 Str << "\n"; |
| 616 } else { | 671 } else { |
| 617 Str << (AssignedRegNum == Item->getRegNum() ? "Reassigning " | 672 Str << (AssignedRegNum == Item->getRegNum() ? "Reassigning " |
| 618 : "Assigning ") | 673 : "Assigning ") |
| 619 << Func->getTarget()->getRegName(AssignedRegNum, IceType_i32) | 674 << Target->getRegName(AssignedRegNum, IceType_i32) << "(r" |
| 620 << "(r" << AssignedRegNum << ") to "; | 675 << AssignedRegNum << ") to "; |
| 621 Item->dump(Func); | 676 Item->dump(Func); |
| 622 Str << "\n"; | 677 Str << "\n"; |
| 623 } | 678 } |
| 624 } | 679 } |
| 625 Item->setRegNum(AssignedRegNum); | 680 Item->setRegNum(AssignedRegNum); |
| 626 } | 681 } |
| 627 } | 682 } |
| 628 | 683 |
| 629 // Implements the linear-scan algorithm. Based on "Linear Scan Register | 684 // Implements the linear-scan algorithm. Based on "Linear Scan Register |
| 630 // Allocation in the Context of SSA Form and Register Constraints" by Hanspeter | 685 // Allocation in the Context of SSA Form and Register Constraints" by Hanspeter |
| (...skipping 29 matching lines...) Expand all Loading... |
| 660 | 715 |
| 661 // Unhandled is already set to all ranges in increasing order of start | 716 // Unhandled is already set to all ranges in increasing order of start |
| 662 // points. | 717 // points. |
| 663 assert(Active.empty()); | 718 assert(Active.empty()); |
| 664 assert(Inactive.empty()); | 719 assert(Inactive.empty()); |
| 665 assert(Handled.empty()); | 720 assert(Handled.empty()); |
| 666 const TargetLowering::RegSetMask RegsInclude = | 721 const TargetLowering::RegSetMask RegsInclude = |
| 667 TargetLowering::RegSet_CallerSave; | 722 TargetLowering::RegSet_CallerSave; |
| 668 const TargetLowering::RegSetMask RegsExclude = TargetLowering::RegSet_None; | 723 const TargetLowering::RegSetMask RegsExclude = TargetLowering::RegSet_None; |
| 669 const llvm::SmallBitVector KillsMask = | 724 const llvm::SmallBitVector KillsMask = |
| 670 Func->getTarget()->getRegisterSet(RegsInclude, RegsExclude); | 725 Target->getRegisterSet(RegsInclude, RegsExclude); |
| 671 | 726 |
| 672 // Allocate memory once outside the loop | 727 // Allocate memory once outside the loop |
| 673 IterationState Iter; | 728 IterationState Iter; |
| 674 Iter.Weights.reserve(NumRegisters); | 729 Iter.Weights.reserve(NumRegisters); |
| 675 Iter.PrecoloredUnhandledMask.reserve(NumRegisters); | 730 Iter.PrecoloredUnhandledMask.reserve(NumRegisters); |
| 676 | 731 |
| 677 while (!Unhandled.empty()) { | 732 while (!Unhandled.empty()) { |
| 678 Iter.Cur = Unhandled.back(); | 733 Iter.Cur = Unhandled.back(); |
| 679 Unhandled.pop_back(); | 734 Unhandled.pop_back(); |
| 680 dumpLiveRangeTrace("\nConsidering ", Iter.Cur); | 735 dumpLiveRangeTrace("\nConsidering ", Iter.Cur); |
| 681 Iter.RegMask = | 736 Iter.RegMask = |
| 682 RegMaskFull & | 737 RegMaskFull & Target->getRegisterSetForType(Iter.Cur->getType()); |
| 683 Func->getTarget()->getRegisterSetForType(Iter.Cur->getType()); | |
| 684 KillsRange.trim(Iter.Cur->getLiveRange().getStart()); | 738 KillsRange.trim(Iter.Cur->getLiveRange().getStart()); |
| 685 | 739 |
| 686 // Check for pre-colored ranges. If Cur is pre-colored, it definitely gets | 740 // Check for pre-colored ranges. If Cur is pre-colored, it definitely gets |
| 687 // that register. Previously processed live ranges would have avoided that | 741 // that register. Previously processed live ranges would have avoided that |
| 688 // register due to it being pre-colored. Future processed live ranges won't | 742 // register due to it being pre-colored. Future processed live ranges won't |
| 689 // evict that register because the live range has infinite weight. | 743 // evict that register because the live range has infinite weight. |
| 690 if (Iter.Cur->hasReg()) { | 744 if (Iter.Cur->hasReg()) { |
| 691 allocatePrecoloredRegister(Iter.Cur); | 745 allocatePrecoloredRegister(Iter.Cur); |
| 692 continue; | 746 continue; |
| 693 } | 747 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 if (Iter.PreferReg == i) | 791 if (Iter.PreferReg == i) |
| 738 Iter.AllowOverlap = false; | 792 Iter.AllowOverlap = false; |
| 739 } | 793 } |
| 740 } | 794 } |
| 741 | 795 |
| 742 // Print info about physical register availability. | 796 // Print info about physical register availability. |
| 743 if (Verbose) { | 797 if (Verbose) { |
| 744 Ostream &Str = Ctx->getStrDump(); | 798 Ostream &Str = Ctx->getStrDump(); |
| 745 for (SizeT i = 0; i < Iter.RegMask.size(); ++i) { | 799 for (SizeT i = 0; i < Iter.RegMask.size(); ++i) { |
| 746 if (Iter.RegMask[i]) { | 800 if (Iter.RegMask[i]) { |
| 747 Str << Func->getTarget()->getRegName(i, IceType_i32) | 801 Str << Target->getRegName(i, IceType_i32) << "(U=" << RegUses[i] |
| 748 << "(U=" << RegUses[i] << ",F=" << Iter.Free[i] | 802 << ",F=" << Iter.Free[i] |
| 749 << ",P=" << Iter.PrecoloredUnhandledMask[i] << ") "; | 803 << ",P=" << Iter.PrecoloredUnhandledMask[i] << ") "; |
| 750 } | 804 } |
| 751 } | 805 } |
| 752 Str << "\n"; | 806 Str << "\n"; |
| 753 } | 807 } |
| 754 | 808 |
| 755 if (Iter.Prefer && (Iter.AllowOverlap || Iter.Free[Iter.PreferReg])) { | 809 if (Iter.Prefer && (Iter.AllowOverlap || Iter.Free[Iter.PreferReg])) { |
| 756 // First choice: a preferred register that is either free or is allowed | 810 // First choice: a preferred register that is either free or is allowed |
| 757 // to overlap with its linked variable. | 811 // to overlap with its linked variable. |
| 758 allocatePreferredRegister(Iter); | 812 allocatePreferredRegister(Iter); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 Str << "\n"; | 882 Str << "\n"; |
| 829 } | 883 } |
| 830 Str << "++++++ Inactive:\n"; | 884 Str << "++++++ Inactive:\n"; |
| 831 for (const Variable *Item : Inactive) { | 885 for (const Variable *Item : Inactive) { |
| 832 dumpLiveRange(Item, Func); | 886 dumpLiveRange(Item, Func); |
| 833 Str << "\n"; | 887 Str << "\n"; |
| 834 } | 888 } |
| 835 } | 889 } |
| 836 | 890 |
| 837 } // end of namespace Ice | 891 } // end of namespace Ice |
| OLD | NEW |