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 |
| (...skipping 207 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 Target = Func->getTarget(); | |
|
Jim Stichnoth
2015/09/04 16:53:10
Actually, Target is probably better initialized in
John
2015/09/04 17:32:25
Done.
| |
| 229 SizeT NumRegs = Target->getNumRegisters(); | |
| 230 RegAliases.resize(NumRegs); | |
| 231 for (SizeT Reg = 0; Reg < NumRegs; ++Reg) { | |
| 232 RegAliases[Reg] = &Target->getAliasesForRegister(Reg); | |
| 233 } | |
| 234 | |
| 228 switch (Kind) { | 235 switch (Kind) { |
| 229 case RAK_Unknown: | 236 case RAK_Unknown: |
| 230 llvm::report_fatal_error("Invalid RAK_Unknown"); | 237 llvm::report_fatal_error("Invalid RAK_Unknown"); |
| 231 break; | 238 break; |
| 232 case RAK_Global: | 239 case RAK_Global: |
| 233 case RAK_Phi: | 240 case RAK_Phi: |
| 234 initForGlobal(); | 241 initForGlobal(); |
| 235 break; | 242 break; |
| 236 case RAK_InfOnly: | 243 case RAK_InfOnly: |
| 237 initForInfOnly(); | 244 initForInfOnly(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 if (I->getNumber() == Start) | 296 if (I->getNumber() == Start) |
| 290 SpillPoint = I; | 297 SpillPoint = I; |
| 291 if (I->getNumber() == End) | 298 if (I->getNumber() == End) |
| 292 FillPoint = I; | 299 FillPoint = I; |
| 293 if (SpillPoint != E) { | 300 if (SpillPoint != E) { |
| 294 // Remove from RegMask any physical registers referenced during Cur's live | 301 // 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 | 302 // range. Start looking after SpillPoint gets set, i.e. once Cur's live |
| 296 // range begins. | 303 // range begins. |
| 297 FOREACH_VAR_IN_INST(Var, *I) { | 304 FOREACH_VAR_IN_INST(Var, *I) { |
| 298 if (Var->hasRegTmp()) | 305 if (Var->hasRegTmp()) |
| 299 Iter.RegMask[Var->getRegNumTmp()] = false; | 306 Iter.RegMask[Var->getRegNumTmp()] = false; |
|
jvoung (off chromium)
2015/09/04 16:14:46
Do you need to go over the aliases here too?
Jim Stichnoth
2015/09/04 16:38:51
Good catch, I think the aliases do need to be remo
John
2015/09/04 17:32:25
Done.
| |
| 300 } | 307 } |
| 301 } | 308 } |
| 302 } | 309 } |
| 303 assert(SpillPoint != Insts.end()); | 310 assert(SpillPoint != Insts.end()); |
| 304 assert(FillPoint != Insts.end()); | 311 assert(FillPoint != Insts.end()); |
| 305 ++FillPoint; | 312 ++FillPoint; |
| 306 // TODO(stichnot): Randomize instead of find_first(). | 313 // TODO(stichnot): Randomize instead of find_first(). |
| 307 int32_t RegNum = Iter.RegMask.find_first(); | 314 int32_t RegNum = Iter.RegMask.find_first(); |
| 308 assert(RegNum != -1); | 315 assert(RegNum != -1); |
| 309 Iter.Cur->setRegNumTmp(RegNum); | 316 Iter.Cur->setRegNumTmp(RegNum); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 333 Moved = true; | 340 Moved = true; |
| 334 } else if (!Item->rangeOverlapsStart(Cur)) { | 341 } else if (!Item->rangeOverlapsStart(Cur)) { |
| 335 // Move Item from Active to Inactive list. | 342 // Move Item from Active to Inactive list. |
| 336 dumpLiveRangeTrace("Inactivating ", Cur); | 343 dumpLiveRangeTrace("Inactivating ", Cur); |
| 337 moveItem(Active, Index, Inactive); | 344 moveItem(Active, Index, Inactive); |
| 338 Moved = true; | 345 Moved = true; |
| 339 } | 346 } |
| 340 if (Moved) { | 347 if (Moved) { |
| 341 // Decrement Item from RegUses[]. | 348 // Decrement Item from RegUses[]. |
| 342 assert(Item->hasRegTmp()); | 349 assert(Item->hasRegTmp()); |
| 343 int32_t RegNum = Item->getRegNumTmp(); | 350 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
| 344 --RegUses[RegNum]; | 351 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
|
Jim Stichnoth
2015/09/04 00:10:20
So I greatly prefer using int32_t rather than int.
John
2015/09/04 17:32:25
This is an excellent case where using auto is supe
| |
| 345 assert(RegUses[RegNum] >= 0); | 352 RegAlias = Aliases.find_next(RegAlias)) { |
| 353 --RegUses[RegAlias]; | |
| 354 assert(RegUses[RegAlias] >= 0); | |
| 355 } | |
| 346 } | 356 } |
| 347 } | 357 } |
| 348 } | 358 } |
| 349 | 359 |
| 350 void LinearScan::handleInactiveRangeExpiredOrReactivated(const Variable *Cur) { | 360 void LinearScan::handleInactiveRangeExpiredOrReactivated(const Variable *Cur) { |
| 351 for (SizeT I = Inactive.size(); I > 0; --I) { | 361 for (SizeT I = Inactive.size(); I > 0; --I) { |
| 352 const SizeT Index = I - 1; | 362 const SizeT Index = I - 1; |
| 353 Variable *Item = Inactive[Index]; | 363 Variable *Item = Inactive[Index]; |
| 354 Item->trimLiveRange(Cur->getLiveRange().getStart()); | 364 Item->trimLiveRange(Cur->getLiveRange().getStart()); |
| 355 if (Item->rangeEndsBefore(Cur)) { | 365 if (Item->rangeEndsBefore(Cur)) { |
| 356 // Move Item from Inactive to Handled list. | 366 // Move Item from Inactive to Handled list. |
| 357 dumpLiveRangeTrace("Expiring ", Cur); | 367 dumpLiveRangeTrace("Expiring ", Cur); |
| 358 moveItem(Inactive, Index, Handled); | 368 moveItem(Inactive, Index, Handled); |
| 359 } else if (Item->rangeOverlapsStart(Cur)) { | 369 } else if (Item->rangeOverlapsStart(Cur)) { |
| 360 // Move Item from Inactive to Active list. | 370 // Move Item from Inactive to Active list. |
| 361 dumpLiveRangeTrace("Reactivating ", Cur); | 371 dumpLiveRangeTrace("Reactivating ", Cur); |
| 362 moveItem(Inactive, Index, Active); | 372 moveItem(Inactive, Index, Active); |
| 363 // Increment Item in RegUses[]. | 373 // Increment Item in RegUses[]. |
| 364 assert(Item->hasRegTmp()); | 374 assert(Item->hasRegTmp()); |
| 365 int32_t RegNum = Item->getRegNumTmp(); | 375 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
| 366 assert(RegUses[RegNum] >= 0); | 376 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 367 ++RegUses[RegNum]; | 377 RegAlias = Aliases.find_next(RegAlias)) { |
| 378 assert(RegUses[RegAlias] >= 0); | |
| 379 ++RegUses[RegAlias]; | |
| 380 } | |
| 368 } | 381 } |
| 369 } | 382 } |
| 370 } | 383 } |
| 371 | 384 |
| 372 // Infer register preference and allowable overlap. Only form a preference when | 385 // Infer register preference and allowable overlap. Only form a preference when |
| 373 // the current Variable has an unambiguous "first" definition. The preference | 386 // the current Variable has an unambiguous "first" definition. The preference |
| 374 // is some source Variable of the defining instruction that either is assigned | 387 // 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 | 388 // 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 | 389 // not free but overlap is allowed. Overlap is allowed when the Variable under |
| 377 // consideration is single-definition, and its definition is a simple | 390 // consideration is single-definition, and its definition is a simple |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 } | 437 } |
| 425 } | 438 } |
| 426 } | 439 } |
| 427 } | 440 } |
| 428 | 441 |
| 429 // Remove registers from the Free[] list where an Inactive range overlaps with | 442 // Remove registers from the Free[] list where an Inactive range overlaps with |
| 430 // the current range. | 443 // the current range. |
| 431 void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) { | 444 void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) { |
| 432 for (const Variable *Item : Inactive) { | 445 for (const Variable *Item : Inactive) { |
| 433 if (Item->rangeOverlaps(Iter.Cur)) { | 446 if (Item->rangeOverlaps(Iter.Cur)) { |
| 434 int32_t RegNum = Item->getRegNumTmp(); | 447 int32_t RegNum = Item->getRegNumTmp(); |
|
jvoung (off chromium)
2015/09/04 16:14:46
Do you need to go over the aliases here too?
Jim Stichnoth
2015/09/04 16:38:51
Yeah, I think so...
John
2015/09/04 17:32:25
Done.
| |
| 435 // Don't assert(Free[RegNum]) because in theory (though probably never in | 448 // Don't assert(Free[RegNum]) because in theory (though probably never in |
| 436 // practice) there could be two inactive variables that were marked with | 449 // practice) there could be two inactive variables that were marked with |
| 437 // AllowOverlap. | 450 // AllowOverlap. |
| 438 Iter.Free[RegNum] = false; | 451 Iter.Free[RegNum] = false; |
| 439 // Disable AllowOverlap if an Inactive variable, which is not Prefer, | 452 // Disable AllowOverlap if an Inactive variable, which is not Prefer, |
| 440 // shares Prefer's register, and has a definition within Cur's live | 453 // shares Prefer's register, and has a definition within Cur's live |
| 441 // range. | 454 // range. |
| 442 if (Iter.AllowOverlap && Item != Iter.Prefer && | 455 if (Iter.AllowOverlap && Item != Iter.Prefer && |
| 443 RegNum == Iter.PreferReg && overlapsDefs(Func, Iter.Cur, Item)) { | 456 RegNum == Iter.PreferReg && overlapsDefs(Func, Iter.Cur, Item)) { |
| 444 Iter.AllowOverlap = false; | 457 Iter.AllowOverlap = false; |
| 445 dumpDisableOverlap(Func, Item, "Inactive"); | 458 dumpDisableOverlap(Func, Item, "Inactive"); |
| 446 } | 459 } |
| 447 } | 460 } |
| 448 } | 461 } |
| 449 } | 462 } |
| 450 | 463 |
| 451 // Remove registers from the Free[] list where an Unhandled pre-colored range | 464 // 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 | 465 // 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 | 466 // 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 | 467 // an early exit check that turns a guaranteed O(N^2) algorithm into expected |
| 455 // linear complexity. | 468 // linear complexity. |
| 456 void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) { | 469 void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) { |
| 457 for (Variable *Item : reverse_range(UnhandledPrecolored)) { | 470 for (Variable *Item : reverse_range(UnhandledPrecolored)) { |
| 458 assert(Item->hasReg()); | 471 assert(Item->hasReg()); |
| 459 if (Iter.Cur->rangeEndsBefore(Item)) | 472 if (Iter.Cur->rangeEndsBefore(Item)) |
| 460 break; | 473 break; |
| 461 if (Item->rangeOverlaps(Iter.Cur)) { | 474 if (Item->rangeOverlaps(Iter.Cur)) { |
| 462 int32_t ItemReg = Item->getRegNum(); // Note: not getRegNumTmp() | 475 const llvm::SmallBitVector &Aliases = |
| 463 Iter.Weights[ItemReg].setWeight(RegWeight::Inf); | 476 *RegAliases[Item->getRegNum()]; // Note: not getRegNumTmp() |
| 464 Iter.Free[ItemReg] = false; | 477 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 465 Iter.PrecoloredUnhandledMask[ItemReg] = true; | 478 RegAlias = Aliases.find_next(RegAlias)) { |
| 466 // Disable Iter.AllowOverlap if the preferred register is one of these | 479 Iter.Weights[RegAlias].setWeight(RegWeight::Inf); |
| 467 // pre-colored unhandled overlapping ranges. | 480 Iter.Free[RegAlias] = false; |
| 468 if (Iter.AllowOverlap && ItemReg == Iter.PreferReg) { | 481 Iter.PrecoloredUnhandledMask[RegAlias] = true; |
| 469 Iter.AllowOverlap = false; | 482 // Disable Iter.AllowOverlap if the preferred register is one of these |
| 470 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled"); | 483 // pre-colored unhandled overlapping ranges. |
| 484 if (Iter.AllowOverlap && RegAlias == Iter.PreferReg) { | |
| 485 Iter.AllowOverlap = false; | |
| 486 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled"); | |
| 487 } | |
| 471 } | 488 } |
| 472 } | 489 } |
| 473 } | 490 } |
| 474 } | 491 } |
| 475 | 492 |
| 476 void LinearScan::allocatePrecoloredRegister(Variable *Cur) { | 493 void LinearScan::allocatePrecoloredRegister(Variable *Cur) { |
| 477 int32_t RegNum = Cur->getRegNum(); | 494 int32_t RegNum = Cur->getRegNum(); |
| 478 // RegNumTmp should have already been set above. | 495 // RegNumTmp should have already been set above. |
| 479 assert(Cur->getRegNumTmp() == RegNum); | 496 assert(Cur->getRegNumTmp() == RegNum); |
| 480 dumpLiveRangeTrace("Precoloring ", Cur); | 497 dumpLiveRangeTrace("Precoloring ", Cur); |
| 481 Active.push_back(Cur); | 498 Active.push_back(Cur); |
| 482 assert(RegUses[RegNum] >= 0); | 499 const llvm::SmallBitVector &Aliases = *RegAliases[RegNum]; |
| 483 ++RegUses[RegNum]; | 500 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 501 RegAlias = Aliases.find_next(RegAlias)) { | |
| 502 assert(RegUses[RegAlias] >= 0); | |
| 503 ++RegUses[RegAlias]; | |
| 504 } | |
| 484 assert(!UnhandledPrecolored.empty()); | 505 assert(!UnhandledPrecolored.empty()); |
| 485 assert(UnhandledPrecolored.back() == Cur); | 506 assert(UnhandledPrecolored.back() == Cur); |
| 486 UnhandledPrecolored.pop_back(); | 507 UnhandledPrecolored.pop_back(); |
| 487 } | 508 } |
| 488 | 509 |
| 489 void LinearScan::allocatePreferredRegister(IterationState &Iter) { | 510 void LinearScan::allocatePreferredRegister(IterationState &Iter) { |
| 490 Iter.Cur->setRegNumTmp(Iter.PreferReg); | 511 Iter.Cur->setRegNumTmp(Iter.PreferReg); |
| 491 dumpLiveRangeTrace("Preferring ", Iter.Cur); | 512 dumpLiveRangeTrace("Preferring ", Iter.Cur); |
| 492 assert(RegUses[Iter.PreferReg] >= 0); | 513 const llvm::SmallBitVector &Aliases = *RegAliases[Iter.PreferReg]; |
| 493 ++RegUses[Iter.PreferReg]; | 514 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 515 RegAlias = Aliases.find_next(RegAlias)) { | |
| 516 assert(RegUses[RegAlias] >= 0); | |
| 517 ++RegUses[RegAlias]; | |
| 518 } | |
| 494 Active.push_back(Iter.Cur); | 519 Active.push_back(Iter.Cur); |
| 495 } | 520 } |
| 496 | 521 |
| 497 void LinearScan::allocateFreeRegister(IterationState &Iter) { | 522 void LinearScan::allocateFreeRegister(IterationState &Iter) { |
| 498 int32_t RegNum = Iter.Free.find_first(); | 523 int32_t RegNum = Iter.Free.find_first(); |
| 499 Iter.Cur->setRegNumTmp(RegNum); | 524 Iter.Cur->setRegNumTmp(RegNum); |
| 500 dumpLiveRangeTrace("Allocating ", Iter.Cur); | 525 dumpLiveRangeTrace("Allocating ", Iter.Cur); |
| 501 assert(RegUses[RegNum] >= 0); | 526 const llvm::SmallBitVector &Aliases = *RegAliases[RegNum]; |
| 502 ++RegUses[RegNum]; | 527 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 528 RegAlias = Aliases.find_next(RegAlias)) { | |
| 529 assert(RegUses[RegAlias] >= 0); | |
| 530 ++RegUses[RegAlias]; | |
| 531 } | |
| 503 Active.push_back(Iter.Cur); | 532 Active.push_back(Iter.Cur); |
| 504 } | 533 } |
| 505 | 534 |
| 506 void LinearScan::handleNoFreeRegisters(IterationState &Iter) { | 535 void LinearScan::handleNoFreeRegisters(IterationState &Iter) { |
| 507 // Check Active ranges. | 536 // Check Active ranges. |
| 508 for (const Variable *Item : Active) { | 537 for (const Variable *Item : Active) { |
| 509 assert(Item->rangeOverlaps(Iter.Cur)); | 538 assert(Item->rangeOverlaps(Iter.Cur)); |
| 510 int32_t RegNum = Item->getRegNumTmp(); | |
| 511 assert(Item->hasRegTmp()); | 539 assert(Item->hasRegTmp()); |
| 512 Iter.Weights[RegNum].addWeight(Item->getWeight(Func)); | 540 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
| 541 // We add the Item's weight to each alias/subregister to represent that, | |
| 542 // should we decide to pick any of them, then we would incur that many | |
| 543 // memory accesses. | |
| 544 RegWeight W = Item->getWeight(Func); | |
| 545 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; | |
| 546 RegAlias = Aliases.find_next(RegAlias)) { | |
| 547 Iter.Weights[RegAlias].addWeight(W); | |
| 548 } | |
| 513 } | 549 } |
| 514 // Same as above, but check Inactive ranges instead of Active. | 550 // Same as above, but check Inactive ranges instead of Active. |
| 515 for (const Variable *Item : Inactive) { | 551 for (const Variable *Item : Inactive) { |
| 516 int32_t RegNum = Item->getRegNumTmp(); | 552 if (!Item->rangeOverlaps(Iter.Cur)) |
| 553 continue; | |
| 517 assert(Item->hasRegTmp()); | 554 assert(Item->hasRegTmp()); |
| 518 if (Item->rangeOverlaps(Iter.Cur)) | 555 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
| 519 Iter.Weights[RegNum].addWeight(Item->getWeight(Func)); | 556 RegWeight W = Item->getWeight(Func); |
| 557 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; | |
| 558 RegAlias = Aliases.find_next(RegAlias)) { | |
| 559 Iter.Weights[RegAlias].addWeight(W); | |
| 560 } | |
| 520 } | 561 } |
| 521 | 562 |
| 522 // All the weights are now calculated. Find the register with smallest | 563 // All the weights are now calculated. Find the register with smallest |
| 523 // weight. | 564 // weight. |
| 524 int32_t MinWeightIndex = Iter.RegMask.find_first(); | 565 int32_t MinWeightIndex = Iter.RegMask.find_first(); |
| 525 // MinWeightIndex must be valid because of the initial RegMask.any() test. | 566 // MinWeightIndex must be valid because of the initial RegMask.any() test. |
| 526 assert(MinWeightIndex >= 0); | 567 assert(MinWeightIndex >= 0); |
| 527 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) { | 568 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) { |
| 528 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex]) | 569 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex]) |
| 529 MinWeightIndex = i; | 570 MinWeightIndex = i; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 541 "infinite-weight live range"); | 582 "infinite-weight live range"); |
| 542 } | 583 } |
| 543 } else { | 584 } else { |
| 544 // Evict all live ranges in Active that register number MinWeightIndex is | 585 // Evict all live ranges in Active that register number MinWeightIndex is |
| 545 // assigned to. | 586 // assigned to. |
| 546 for (SizeT I = Active.size(); I > 0; --I) { | 587 for (SizeT I = Active.size(); I > 0; --I) { |
| 547 const SizeT Index = I - 1; | 588 const SizeT Index = I - 1; |
| 548 Variable *Item = Active[Index]; | 589 Variable *Item = Active[Index]; |
| 549 if (Item->getRegNumTmp() == MinWeightIndex) { | 590 if (Item->getRegNumTmp() == MinWeightIndex) { |
| 550 dumpLiveRangeTrace("Evicting ", Item); | 591 dumpLiveRangeTrace("Evicting ", Item); |
| 551 --RegUses[MinWeightIndex]; | 592 const llvm::SmallBitVector &Aliases = *RegAliases[MinWeightIndex]; |
| 552 assert(RegUses[MinWeightIndex] >= 0); | 593 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 594 RegAlias = Aliases.find_next(RegAlias)) { | |
| 595 --RegUses[RegAlias]; | |
| 596 assert(RegUses[RegAlias] >= 0); | |
| 597 } | |
| 553 Item->setRegNumTmp(Variable::NoRegister); | 598 Item->setRegNumTmp(Variable::NoRegister); |
| 554 moveItem(Active, Index, Handled); | 599 moveItem(Active, Index, Handled); |
| 555 } | 600 } |
| 556 } | 601 } |
| 557 // Do the same for Inactive. | 602 // Do the same for Inactive. |
| 558 for (SizeT I = Inactive.size(); I > 0; --I) { | 603 for (SizeT I = Inactive.size(); I > 0; --I) { |
| 559 const SizeT Index = I - 1; | 604 const SizeT Index = I - 1; |
| 560 Variable *Item = Inactive[Index]; | 605 Variable *Item = Inactive[Index]; |
| 561 // Note: The Item->rangeOverlaps(Cur) clause is not part of the | 606 // Note: The Item->rangeOverlaps(Cur) clause is not part of the |
| 562 // description of AssignMemLoc() in the original paper. But there | 607 // description of AssignMemLoc() in the original paper. But there |
| 563 // doesn't seem to be any need to evict an inactive live range that | 608 // 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 | 609 // 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 | 610 // especially bad if we would end up evicting an infinite-weight but |
| 566 // currently-inactive live range. The most common situation for this | 611 // currently-inactive live range. The most common situation for this |
| 567 // would be a scratch register kill set for call instructions. | 612 // would be a scratch register kill set for call instructions. |
| 568 if (Item->getRegNumTmp() == MinWeightIndex && | 613 if (Item->getRegNumTmp() == MinWeightIndex && |
| 569 Item->rangeOverlaps(Iter.Cur)) { | 614 Item->rangeOverlaps(Iter.Cur)) { |
| 570 dumpLiveRangeTrace("Evicting ", Item); | 615 dumpLiveRangeTrace("Evicting ", Item); |
| 571 Item->setRegNumTmp(Variable::NoRegister); | 616 Item->setRegNumTmp(Variable::NoRegister); |
| 572 moveItem(Inactive, Index, Handled); | 617 moveItem(Inactive, Index, Handled); |
| 573 } | 618 } |
| 574 } | 619 } |
| 575 // Assign the register to Cur. | 620 // Assign the register to Cur. |
| 576 Iter.Cur->setRegNumTmp(MinWeightIndex); | 621 Iter.Cur->setRegNumTmp(MinWeightIndex); |
| 577 assert(RegUses[MinWeightIndex] >= 0); | 622 const llvm::SmallBitVector &Aliases = *RegAliases[MinWeightIndex]; |
| 578 ++RegUses[MinWeightIndex]; | 623 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 624 RegAlias = Aliases.find_next(RegAlias)) { | |
| 625 assert(RegUses[RegAlias] >= 0); | |
| 626 ++RegUses[RegAlias]; | |
| 627 } | |
| 579 Active.push_back(Iter.Cur); | 628 Active.push_back(Iter.Cur); |
| 580 dumpLiveRangeTrace("Allocating ", Iter.Cur); | 629 dumpLiveRangeTrace("Allocating ", Iter.Cur); |
| 581 } | 630 } |
| 582 } | 631 } |
| 583 | 632 |
| 584 void LinearScan::assignFinalRegisters( | 633 void LinearScan::assignFinalRegisters( |
| 585 const llvm::SmallBitVector &RegMaskFull, | 634 const llvm::SmallBitVector &RegMaskFull, |
| 586 const llvm::SmallBitVector &PreDefinedRegisters, bool Randomized) { | 635 const llvm::SmallBitVector &PreDefinedRegisters, bool Randomized) { |
| 587 const size_t NumRegisters = RegMaskFull.size(); | 636 const size_t NumRegisters = RegMaskFull.size(); |
| 588 llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters); | 637 llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters); |
| 589 if (Randomized) { | 638 if (Randomized) { |
| 590 // Create a random number generator for regalloc randomization. Merge | 639 // Create a random number generator for regalloc randomization. Merge |
| 591 // function's sequence and Kind value as the Salt. Because regAlloc() is | 640 // 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 | 641 // 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 | 642 // Kind == RAK_Phi to determine the lowest-order bit to make sure the Salt |
| 594 // is different. | 643 // is different. |
| 595 uint64_t Salt = | 644 uint64_t Salt = |
| 596 (Func->getSequenceNumber() << 1) ^ (Kind == RAK_Phi ? 0u : 1u); | 645 (Func->getSequenceNumber() << 1) ^ (Kind == RAK_Phi ? 0u : 1u); |
| 597 Func->getTarget()->makeRandomRegisterPermutation( | 646 Func->getTarget()->makeRandomRegisterPermutation( |
|
Jim Stichnoth
2015/09/04 16:50:17
Can you change this and basically all Func->getTar
John
2015/09/04 17:32:25
Done.
| |
| 598 Permutation, PreDefinedRegisters | ~RegMaskFull, Salt); | 647 Permutation, PreDefinedRegisters | ~RegMaskFull, Salt); |
| 599 } | 648 } |
| 600 | 649 |
| 601 // Finish up by setting RegNum = RegNumTmp (or a random permutation thereof) | 650 // Finish up by setting RegNum = RegNumTmp (or a random permutation thereof) |
| 602 // for each Variable. | 651 // for each Variable. |
| 603 for (Variable *Item : Handled) { | 652 for (Variable *Item : Handled) { |
| 604 int32_t RegNum = Item->getRegNumTmp(); | 653 int32_t RegNum = Item->getRegNumTmp(); |
| 605 int32_t AssignedRegNum = RegNum; | 654 int32_t AssignedRegNum = RegNum; |
| 606 | 655 |
| 607 if (Randomized && Item->hasRegTmp() && !Item->hasReg()) { | 656 if (Randomized && Item->hasRegTmp() && !Item->hasReg()) { |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 828 Str << "\n"; | 877 Str << "\n"; |
| 829 } | 878 } |
| 830 Str << "++++++ Inactive:\n"; | 879 Str << "++++++ Inactive:\n"; |
| 831 for (const Variable *Item : Inactive) { | 880 for (const Variable *Item : Inactive) { |
| 832 dumpLiveRange(Item, Func); | 881 dumpLiveRange(Item, Func); |
| 833 Str << "\n"; | 882 Str << "\n"; |
| 834 } | 883 } |
| 835 } | 884 } |
| 836 | 885 |
| 837 } // end of namespace Ice | 886 } // end of namespace Ice |
| OLD | NEW |