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 TargetLowering *Target = Func->getTarget(); | |
|
Jim Stichnoth
2015/09/03 17:48:49
I think maybe it's about time to make TargetLoweri
John
2015/09/03 22:38:24
Done.
| |
| 229 SizeT NumRegs = Target->getNumRegisters(); | |
| 230 RegAliases.resize(NumRegs); | |
| 231 for (SizeT Reg = 0; Reg < NumRegs; ++Reg) { | |
| 232 RegAliases[Reg] = &Target->getAliasesForRegister(Reg); | |
|
Jim Stichnoth
2015/09/03 17:48:49
Would it be easier/cleaner to just call something
John
2015/09/03 22:38:24
As we spoke offline, the underlying types holding
| |
| 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after 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 RegNum = Aliases.find_first(); RegNum >= 0; |
|
Jim Stichnoth
2015/09/03 17:48:49
This repeated loop pattern uses 4 different variab
John
2015/09/03 22:38:24
Done.
| |
| 345 assert(RegUses[RegNum] >= 0); | 352 RegNum = Aliases.find_next(RegNum)) { |
| 353 --RegUses[RegNum]; | |
| 354 assert(RegUses[RegNum] >= 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 RegNum = Aliases.find_first(); RegNum >= 0; |
| 367 ++RegUses[RegNum]; | 377 RegNum = Aliases.find_next(RegNum)) { |
| 378 assert(RegUses[RegNum] >= 0); | |
| 379 ++RegUses[RegNum]; | |
| 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 ItemReg = Aliases.find_first(); ItemReg >= 0; |
| 465 Iter.PrecoloredUnhandledMask[ItemReg] = true; | 478 ItemReg = Aliases.find_next(ItemReg)) { |
| 466 // Disable Iter.AllowOverlap if the preferred register is one of these | 479 // TODO(jpp): This loop should not update the weight of "parent" (i.e., |
|
Jim Stichnoth
2015/09/03 17:48:49
I don't understand this TODO. The purpose of this
John
2015/09/03 22:38:24
Misplaced TODO.
| |
| 467 // pre-colored unhandled overlapping ranges. | 480 // larger) registers if its current weight is more than the new weight. |
| 468 if (Iter.AllowOverlap && ItemReg == Iter.PreferReg) { | 481 Iter.Weights[ItemReg].setWeight(RegWeight::Inf); |
| 469 Iter.AllowOverlap = false; | 482 Iter.Free[ItemReg] = false; |
| 470 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled"); | 483 Iter.PrecoloredUnhandledMask[ItemReg] = true; |
| 484 // Disable Iter.AllowOverlap if the preferred register is one of these | |
| 485 // pre-colored unhandled overlapping ranges. | |
| 486 if (Iter.AllowOverlap && ItemReg == Iter.PreferReg) { | |
| 487 Iter.AllowOverlap = false; | |
| 488 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled"); | |
| 489 } | |
| 471 } | 490 } |
| 472 } | 491 } |
| 473 } | 492 } |
| 474 } | 493 } |
| 475 | 494 |
| 476 void LinearScan::allocatePrecoloredRegister(Variable *Cur) { | 495 void LinearScan::allocatePrecoloredRegister(Variable *Cur) { |
| 477 int32_t RegNum = Cur->getRegNum(); | 496 int32_t RegNum = Cur->getRegNum(); |
| 478 // RegNumTmp should have already been set above. | 497 // RegNumTmp should have already been set above. |
| 479 assert(Cur->getRegNumTmp() == RegNum); | 498 assert(Cur->getRegNumTmp() == RegNum); |
| 480 dumpLiveRangeTrace("Precoloring ", Cur); | 499 dumpLiveRangeTrace("Precoloring ", Cur); |
| 481 Active.push_back(Cur); | 500 Active.push_back(Cur); |
| 482 assert(RegUses[RegNum] >= 0); | 501 const llvm::SmallBitVector &Aliases = *RegAliases[RegNum]; |
| 483 ++RegUses[RegNum]; | 502 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 503 RegAlias = Aliases.find_next(RegAlias)) { | |
| 504 assert(RegUses[RegAlias] >= 0); | |
| 505 ++RegUses[RegAlias]; | |
| 506 } | |
| 484 assert(!UnhandledPrecolored.empty()); | 507 assert(!UnhandledPrecolored.empty()); |
| 485 assert(UnhandledPrecolored.back() == Cur); | 508 assert(UnhandledPrecolored.back() == Cur); |
| 486 UnhandledPrecolored.pop_back(); | 509 UnhandledPrecolored.pop_back(); |
| 487 } | 510 } |
| 488 | 511 |
| 489 void LinearScan::allocatePreferredRegister(IterationState &Iter) { | 512 void LinearScan::allocatePreferredRegister(IterationState &Iter) { |
| 490 Iter.Cur->setRegNumTmp(Iter.PreferReg); | 513 Iter.Cur->setRegNumTmp(Iter.PreferReg); |
| 491 dumpLiveRangeTrace("Preferring ", Iter.Cur); | 514 dumpLiveRangeTrace("Preferring ", Iter.Cur); |
| 492 assert(RegUses[Iter.PreferReg] >= 0); | 515 const llvm::SmallBitVector &Aliases = *RegAliases[Iter.PreferReg]; |
| 493 ++RegUses[Iter.PreferReg]; | 516 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 517 RegAlias = Aliases.find_next(RegAlias)) { | |
| 518 assert(RegUses[RegAlias] >= 0); | |
| 519 ++RegUses[RegAlias]; | |
| 520 } | |
| 494 Active.push_back(Iter.Cur); | 521 Active.push_back(Iter.Cur); |
| 495 } | 522 } |
| 496 | 523 |
| 497 void LinearScan::allocateFreeRegister(IterationState &Iter) { | 524 void LinearScan::allocateFreeRegister(IterationState &Iter) { |
| 498 int32_t RegNum = Iter.Free.find_first(); | 525 int32_t RegNum = Iter.Free.find_first(); |
| 499 Iter.Cur->setRegNumTmp(RegNum); | 526 Iter.Cur->setRegNumTmp(RegNum); |
| 500 dumpLiveRangeTrace("Allocating ", Iter.Cur); | 527 dumpLiveRangeTrace("Allocating ", Iter.Cur); |
| 501 assert(RegUses[RegNum] >= 0); | 528 const llvm::SmallBitVector &Aliases = *RegAliases[RegNum]; |
| 502 ++RegUses[RegNum]; | 529 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 530 RegAlias = Aliases.find_next(RegAlias)) { | |
| 531 assert(RegUses[RegAlias] >= 0); | |
| 532 ++RegUses[RegAlias]; | |
| 533 } | |
| 503 Active.push_back(Iter.Cur); | 534 Active.push_back(Iter.Cur); |
| 504 } | 535 } |
| 505 | 536 |
| 506 void LinearScan::handleNoFreeRegisters(IterationState &Iter) { | 537 void LinearScan::handleNoFreeRegisters(IterationState &Iter) { |
| 507 // Check Active ranges. | 538 // Check Active ranges. |
| 508 for (const Variable *Item : Active) { | 539 for (const Variable *Item : Active) { |
| 509 assert(Item->rangeOverlaps(Iter.Cur)); | 540 assert(Item->rangeOverlaps(Iter.Cur)); |
| 510 int32_t RegNum = Item->getRegNumTmp(); | 541 RegWeight W; |
| 511 assert(Item->hasRegTmp()); | 542 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
| 512 Iter.Weights[RegNum].addWeight(Item->getWeight(Func)); | 543 for (int32_t RegNum = Aliases.find_first(); RegNum >= 0; |
| 544 RegNum = Aliases.find_next(RegNum)) { | |
| 545 assert(Item->hasRegTmp()); | |
| 546 RegWeight Tmp = Item->getWeight(Func); | |
| 547 if (W < Tmp) | |
| 548 W = Tmp; | |
| 549 } | |
| 550 Iter.Weights[Item->getRegNumTmp()].addWeight(W); | |
|
Jim Stichnoth
2015/09/03 17:48:49
Should probably drop a TODO here about the fact th
John
2015/09/03 22:38:25
Done.
| |
| 513 } | 551 } |
| 514 // Same as above, but check Inactive ranges instead of Active. | 552 // Same as above, but check Inactive ranges instead of Active. |
| 515 for (const Variable *Item : Inactive) { | 553 for (const Variable *Item : Inactive) { |
| 516 int32_t RegNum = Item->getRegNumTmp(); | 554 bool HasWeight = false; |
| 517 assert(Item->hasRegTmp()); | 555 RegWeight W; |
| 518 if (Item->rangeOverlaps(Iter.Cur)) | 556 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
| 519 Iter.Weights[RegNum].addWeight(Item->getWeight(Func)); | 557 for (int32_t RegNum = Aliases.find_first(); RegNum >= 0; |
| 558 RegNum = Aliases.find_next(RegNum)) { | |
| 559 assert(Item->hasRegTmp()); | |
| 560 if (Item->rangeOverlaps(Iter.Cur)) { | |
| 561 HasWeight = true; | |
| 562 RegWeight Tmp = Item->getWeight(Func); | |
| 563 if (W < Tmp) | |
| 564 W = Tmp; | |
| 565 } | |
| 566 } | |
| 567 if (HasWeight) { | |
| 568 Iter.Weights[Item->getRegNumTmp()].addWeight(W); | |
| 569 } | |
| 520 } | 570 } |
| 521 | 571 |
| 522 // All the weights are now calculated. Find the register with smallest | 572 // All the weights are now calculated. Find the register with smallest |
| 523 // weight. | 573 // weight. |
| 524 int32_t MinWeightIndex = Iter.RegMask.find_first(); | 574 int32_t MinWeightIndex = Iter.RegMask.find_first(); |
| 525 // MinWeightIndex must be valid because of the initial RegMask.any() test. | 575 // MinWeightIndex must be valid because of the initial RegMask.any() test. |
| 526 assert(MinWeightIndex >= 0); | 576 assert(MinWeightIndex >= 0); |
| 527 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) { | 577 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) { |
| 528 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex]) | 578 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex]) |
| 529 MinWeightIndex = i; | 579 MinWeightIndex = i; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 541 "infinite-weight live range"); | 591 "infinite-weight live range"); |
| 542 } | 592 } |
| 543 } else { | 593 } else { |
| 544 // Evict all live ranges in Active that register number MinWeightIndex is | 594 // Evict all live ranges in Active that register number MinWeightIndex is |
| 545 // assigned to. | 595 // assigned to. |
| 546 for (SizeT I = Active.size(); I > 0; --I) { | 596 for (SizeT I = Active.size(); I > 0; --I) { |
| 547 const SizeT Index = I - 1; | 597 const SizeT Index = I - 1; |
| 548 Variable *Item = Active[Index]; | 598 Variable *Item = Active[Index]; |
| 549 if (Item->getRegNumTmp() == MinWeightIndex) { | 599 if (Item->getRegNumTmp() == MinWeightIndex) { |
| 550 dumpLiveRangeTrace("Evicting ", Item); | 600 dumpLiveRangeTrace("Evicting ", Item); |
| 551 --RegUses[MinWeightIndex]; | 601 const llvm::SmallBitVector &Aliases = *RegAliases[MinWeightIndex]; |
| 552 assert(RegUses[MinWeightIndex] >= 0); | 602 for (int32_t Reg = Aliases.find_first(); Reg >= 0; |
| 603 Reg = Aliases.find_next(Reg)) { | |
| 604 --RegUses[Reg]; | |
| 605 assert(RegUses[Reg] >= 0); | |
| 606 } | |
| 553 Item->setRegNumTmp(Variable::NoRegister); | 607 Item->setRegNumTmp(Variable::NoRegister); |
| 554 moveItem(Active, Index, Handled); | 608 moveItem(Active, Index, Handled); |
| 555 } | 609 } |
| 556 } | 610 } |
| 557 // Do the same for Inactive. | 611 // Do the same for Inactive. |
| 558 for (SizeT I = Inactive.size(); I > 0; --I) { | 612 for (SizeT I = Inactive.size(); I > 0; --I) { |
| 559 const SizeT Index = I - 1; | 613 const SizeT Index = I - 1; |
| 560 Variable *Item = Inactive[Index]; | 614 Variable *Item = Inactive[Index]; |
| 561 // Note: The Item->rangeOverlaps(Cur) clause is not part of the | 615 // Note: The Item->rangeOverlaps(Cur) clause is not part of the |
| 562 // description of AssignMemLoc() in the original paper. But there | 616 // description of AssignMemLoc() in the original paper. But there |
| 563 // doesn't seem to be any need to evict an inactive live range that | 617 // 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 | 618 // 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 | 619 // especially bad if we would end up evicting an infinite-weight but |
| 566 // currently-inactive live range. The most common situation for this | 620 // currently-inactive live range. The most common situation for this |
| 567 // would be a scratch register kill set for call instructions. | 621 // would be a scratch register kill set for call instructions. |
| 568 if (Item->getRegNumTmp() == MinWeightIndex && | 622 if (Item->getRegNumTmp() == MinWeightIndex && |
| 569 Item->rangeOverlaps(Iter.Cur)) { | 623 Item->rangeOverlaps(Iter.Cur)) { |
| 570 dumpLiveRangeTrace("Evicting ", Item); | 624 dumpLiveRangeTrace("Evicting ", Item); |
| 571 Item->setRegNumTmp(Variable::NoRegister); | 625 Item->setRegNumTmp(Variable::NoRegister); |
| 572 moveItem(Inactive, Index, Handled); | 626 moveItem(Inactive, Index, Handled); |
| 573 } | 627 } |
| 574 } | 628 } |
| 575 // Assign the register to Cur. | 629 // Assign the register to Cur. |
| 576 Iter.Cur->setRegNumTmp(MinWeightIndex); | 630 Iter.Cur->setRegNumTmp(MinWeightIndex); |
| 577 assert(RegUses[MinWeightIndex] >= 0); | 631 const llvm::SmallBitVector &Aliases = *RegAliases[MinWeightIndex]; |
| 578 ++RegUses[MinWeightIndex]; | 632 for (int32_t Reg = Aliases.find_first(); Reg >= 0; |
| 633 Reg = Aliases.find_next(Reg)) { | |
| 634 assert(RegUses[Reg] >= 0); | |
| 635 ++RegUses[Reg]; | |
| 636 } | |
| 579 Active.push_back(Iter.Cur); | 637 Active.push_back(Iter.Cur); |
| 580 dumpLiveRangeTrace("Allocating ", Iter.Cur); | 638 dumpLiveRangeTrace("Allocating ", Iter.Cur); |
| 581 } | 639 } |
| 582 } | 640 } |
| 583 | 641 |
| 584 void LinearScan::assignFinalRegisters( | 642 void LinearScan::assignFinalRegisters( |
| 585 const llvm::SmallBitVector &RegMaskFull, | 643 const llvm::SmallBitVector &RegMaskFull, |
| 586 const llvm::SmallBitVector &PreDefinedRegisters, bool Randomized) { | 644 const llvm::SmallBitVector &PreDefinedRegisters, bool Randomized) { |
| 587 const size_t NumRegisters = RegMaskFull.size(); | 645 const size_t NumRegisters = RegMaskFull.size(); |
| 588 llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters); | 646 llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 828 Str << "\n"; | 886 Str << "\n"; |
| 829 } | 887 } |
| 830 Str << "++++++ Inactive:\n"; | 888 Str << "++++++ Inactive:\n"; |
| 831 for (const Variable *Item : Inactive) { | 889 for (const Variable *Item : Inactive) { |
| 832 dumpLiveRange(Item, Func); | 890 dumpLiveRange(Item, Func); |
| 833 Str << "\n"; | 891 Str << "\n"; |
| 834 } | 892 } |
| 835 } | 893 } |
| 836 | 894 |
| 837 } // end of namespace Ice | 895 } // end of namespace Ice |
| OLD | NEW |