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

Side by Side Diff: src/IceRegAlloc.cpp

Issue 848193003: Subzero: Add locking to prepare for multithreaded translation. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Rebase Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceOperand.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceRegAlloc.cpp - Linear-scan implementation -----------===// 1 //===- subzero/src/IceRegAlloc.cpp - Linear-scan implementation -----------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file implements the LinearScan class, which performs the 10 // This file implements the LinearScan class, which performs the
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 // two interfering variables to share the same register in certain 257 // two interfering variables to share the same register in certain
258 // cases. 258 // cases.
259 // 259 //
260 // Requires running Cfg::liveness(Liveness_Intervals) in 260 // Requires running Cfg::liveness(Liveness_Intervals) in
261 // preparation. Results are assigned to Variable::RegNum for each 261 // preparation. Results are assigned to Variable::RegNum for each
262 // Variable. 262 // Variable.
263 void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull, 263 void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull,
264 bool Randomized) { 264 bool Randomized) {
265 TimerMarker T(TimerStack::TT_linearScan, Func); 265 TimerMarker T(TimerStack::TT_linearScan, Func);
266 assert(RegMaskFull.any()); // Sanity check 266 assert(RegMaskFull.any()); // Sanity check
267 Ostream &Str = Func->getContext()->getStrDump(); 267 GlobalContext *Ctx = Func->getContext();
268 const bool Verbose = 268 const bool Verbose =
269 ALLOW_DUMP && Func->getContext()->isVerbose(IceV_LinearScan); 269 ALLOW_DUMP && Ctx->isVerbose(IceV_LinearScan);
270 if (Verbose)
271 Ctx->lockStr();
270 Func->resetCurrentNode(); 272 Func->resetCurrentNode();
271 VariablesMetadata *VMetadata = Func->getVMetadata(); 273 VariablesMetadata *VMetadata = Func->getVMetadata();
272 const size_t NumRegisters = RegMaskFull.size(); 274 const size_t NumRegisters = RegMaskFull.size();
273 llvm::SmallBitVector PreDefinedRegisters(NumRegisters); 275 llvm::SmallBitVector PreDefinedRegisters(NumRegisters);
274 if (Randomized) { 276 if (Randomized) {
275 for (Variable *Var : UnhandledPrecolored) { 277 for (Variable *Var : UnhandledPrecolored) {
276 PreDefinedRegisters[Var->getRegNum()] = true; 278 PreDefinedRegisters[Var->getRegNum()] = true;
277 } 279 }
278 } 280 }
279 281
(...skipping 13 matching lines...) Expand all
293 const TargetLowering::RegSetMask RegsInclude = 295 const TargetLowering::RegSetMask RegsInclude =
294 TargetLowering::RegSet_CallerSave; 296 TargetLowering::RegSet_CallerSave;
295 const TargetLowering::RegSetMask RegsExclude = TargetLowering::RegSet_None; 297 const TargetLowering::RegSetMask RegsExclude = TargetLowering::RegSet_None;
296 const llvm::SmallBitVector KillsMask = 298 const llvm::SmallBitVector KillsMask =
297 Func->getTarget()->getRegisterSet(RegsInclude, RegsExclude); 299 Func->getTarget()->getRegisterSet(RegsInclude, RegsExclude);
298 300
299 while (!Unhandled.empty()) { 301 while (!Unhandled.empty()) {
300 Variable *Cur = Unhandled.back(); 302 Variable *Cur = Unhandled.back();
301 Unhandled.pop_back(); 303 Unhandled.pop_back();
302 if (Verbose) { 304 if (Verbose) {
305 Ostream &Str = Ctx->getStrDump();
303 Str << "\nConsidering "; 306 Str << "\nConsidering ";
304 dumpLiveRange(Cur, Func); 307 dumpLiveRange(Cur, Func);
305 Str << "\n"; 308 Str << "\n";
306 } 309 }
307 const llvm::SmallBitVector RegMask = 310 const llvm::SmallBitVector RegMask =
308 RegMaskFull & Func->getTarget()->getRegisterSetForType(Cur->getType()); 311 RegMaskFull & Func->getTarget()->getRegisterSetForType(Cur->getType());
309 KillsRange.trim(Cur->getLiveRange().getStart()); 312 KillsRange.trim(Cur->getLiveRange().getStart());
310 313
311 // Check for precolored ranges. If Cur is precolored, it 314 // Check for precolored ranges. If Cur is precolored, it
312 // definitely gets that register. Previously processed live 315 // definitely gets that register. Previously processed live
313 // ranges would have avoided that register due to it being 316 // ranges would have avoided that register due to it being
314 // precolored. Future processed live ranges won't evict that 317 // precolored. Future processed live ranges won't evict that
315 // register because the live range has infinite weight. 318 // register because the live range has infinite weight.
316 if (Cur->hasReg()) { 319 if (Cur->hasReg()) {
317 int32_t RegNum = Cur->getRegNum(); 320 int32_t RegNum = Cur->getRegNum();
318 // RegNumTmp should have already been set above. 321 // RegNumTmp should have already been set above.
319 assert(Cur->getRegNumTmp() == RegNum); 322 assert(Cur->getRegNumTmp() == RegNum);
320 if (Verbose) { 323 if (Verbose) {
324 Ostream &Str = Ctx->getStrDump();
321 Str << "Precoloring "; 325 Str << "Precoloring ";
322 dumpLiveRange(Cur, Func); 326 dumpLiveRange(Cur, Func);
323 Str << "\n"; 327 Str << "\n";
324 } 328 }
325 Active.push_back(Cur); 329 Active.push_back(Cur);
326 assert(RegUses[RegNum] >= 0); 330 assert(RegUses[RegNum] >= 0);
327 ++RegUses[RegNum]; 331 ++RegUses[RegNum];
328 assert(!UnhandledPrecolored.empty()); 332 assert(!UnhandledPrecolored.empty());
329 assert(UnhandledPrecolored.back() == Cur); 333 assert(UnhandledPrecolored.back() == Cur);
330 UnhandledPrecolored.pop_back(); 334 UnhandledPrecolored.pop_back();
331 continue; 335 continue;
332 } 336 }
333 337
334 // Check for active ranges that have expired or become inactive. 338 // Check for active ranges that have expired or become inactive.
335 for (SizeT I = Active.size(); I > 0; --I) { 339 for (SizeT I = Active.size(); I > 0; --I) {
336 const SizeT Index = I - 1; 340 const SizeT Index = I - 1;
337 Variable *Item = Active[Index]; 341 Variable *Item = Active[Index];
338 Item->trimLiveRange(Cur->getLiveRange().getStart()); 342 Item->trimLiveRange(Cur->getLiveRange().getStart());
339 bool Moved = false; 343 bool Moved = false;
340 if (Item->rangeEndsBefore(Cur)) { 344 if (Item->rangeEndsBefore(Cur)) {
341 // Move Item from Active to Handled list. 345 // Move Item from Active to Handled list.
342 if (Verbose) { 346 if (Verbose) {
347 Ostream &Str = Ctx->getStrDump();
343 Str << "Expiring "; 348 Str << "Expiring ";
344 dumpLiveRange(Item, Func); 349 dumpLiveRange(Item, Func);
345 Str << "\n"; 350 Str << "\n";
346 } 351 }
347 moveItem(Active, Index, Handled); 352 moveItem(Active, Index, Handled);
348 Moved = true; 353 Moved = true;
349 } else if (!Item->rangeOverlapsStart(Cur)) { 354 } else if (!Item->rangeOverlapsStart(Cur)) {
350 // Move Item from Active to Inactive list. 355 // Move Item from Active to Inactive list.
351 if (Verbose) { 356 if (Verbose) {
357 Ostream &Str = Ctx->getStrDump();
352 Str << "Inactivating "; 358 Str << "Inactivating ";
353 dumpLiveRange(Item, Func); 359 dumpLiveRange(Item, Func);
354 Str << "\n"; 360 Str << "\n";
355 } 361 }
356 moveItem(Active, Index, Inactive); 362 moveItem(Active, Index, Inactive);
357 Moved = true; 363 Moved = true;
358 } 364 }
359 if (Moved) { 365 if (Moved) {
360 // Decrement Item from RegUses[]. 366 // Decrement Item from RegUses[].
361 assert(Item->hasRegTmp()); 367 assert(Item->hasRegTmp());
362 int32_t RegNum = Item->getRegNumTmp(); 368 int32_t RegNum = Item->getRegNumTmp();
363 --RegUses[RegNum]; 369 --RegUses[RegNum];
364 assert(RegUses[RegNum] >= 0); 370 assert(RegUses[RegNum] >= 0);
365 } 371 }
366 } 372 }
367 373
368 // Check for inactive ranges that have expired or reactivated. 374 // Check for inactive ranges that have expired or reactivated.
369 for (SizeT I = Inactive.size(); I > 0; --I) { 375 for (SizeT I = Inactive.size(); I > 0; --I) {
370 const SizeT Index = I - 1; 376 const SizeT Index = I - 1;
371 Variable *Item = Inactive[Index]; 377 Variable *Item = Inactive[Index];
372 Item->trimLiveRange(Cur->getLiveRange().getStart()); 378 Item->trimLiveRange(Cur->getLiveRange().getStart());
373 if (Item->rangeEndsBefore(Cur)) { 379 if (Item->rangeEndsBefore(Cur)) {
374 // Move Item from Inactive to Handled list. 380 // Move Item from Inactive to Handled list.
375 if (Verbose) { 381 if (Verbose) {
382 Ostream &Str = Ctx->getStrDump();
376 Str << "Expiring "; 383 Str << "Expiring ";
377 dumpLiveRange(Item, Func); 384 dumpLiveRange(Item, Func);
378 Str << "\n"; 385 Str << "\n";
379 } 386 }
380 moveItem(Inactive, Index, Handled); 387 moveItem(Inactive, Index, Handled);
381 } else if (Item->rangeOverlapsStart(Cur)) { 388 } else if (Item->rangeOverlapsStart(Cur)) {
382 // Move Item from Inactive to Active list. 389 // Move Item from Inactive to Active list.
383 if (Verbose) { 390 if (Verbose) {
391 Ostream &Str = Ctx->getStrDump();
384 Str << "Reactivating "; 392 Str << "Reactivating ";
385 dumpLiveRange(Item, Func); 393 dumpLiveRange(Item, Func);
386 Str << "\n"; 394 Str << "\n";
387 } 395 }
388 moveItem(Inactive, Index, Active); 396 moveItem(Inactive, Index, Active);
389 // Increment Item in RegUses[]. 397 // Increment Item in RegUses[].
390 assert(Item->hasRegTmp()); 398 assert(Item->hasRegTmp());
391 int32_t RegNum = Item->getRegNumTmp(); 399 int32_t RegNum = Item->getRegNumTmp();
392 assert(RegUses[RegNum] >= 0); 400 assert(RegUses[RegNum] >= 0);
393 ++RegUses[RegNum]; 401 ++RegUses[RegNum];
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 IsSingleDef && IsAssign && !overlapsDefs(Func, Cur, SrcVar); 447 IsSingleDef && IsAssign && !overlapsDefs(Func, Cur, SrcVar);
440 } 448 }
441 if (AllowOverlap || Free[SrcReg]) { 449 if (AllowOverlap || Free[SrcReg]) {
442 Prefer = SrcVar; 450 Prefer = SrcVar;
443 PreferReg = SrcReg; 451 PreferReg = SrcReg;
444 } 452 }
445 } 453 }
446 } 454 }
447 } 455 }
448 if (Verbose && Prefer) { 456 if (Verbose && Prefer) {
457 Ostream &Str = Ctx->getStrDump();
449 Str << "Initial Prefer="; 458 Str << "Initial Prefer=";
450 Prefer->dump(Func); 459 Prefer->dump(Func);
451 Str << " R=" << PreferReg << " LIVE=" << Prefer->getLiveRange() 460 Str << " R=" << PreferReg << " LIVE=" << Prefer->getLiveRange()
452 << " Overlap=" << AllowOverlap << "\n"; 461 << " Overlap=" << AllowOverlap << "\n";
453 } 462 }
454 } 463 }
455 } 464 }
456 465
457 // Remove registers from the Free[] list where an Inactive range 466 // Remove registers from the Free[] list where an Inactive range
458 // overlaps with the current range. 467 // overlaps with the current range.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 for (int i = KillsMask.find_first(); i != -1; 533 for (int i = KillsMask.find_first(); i != -1;
525 i = KillsMask.find_next(i)) { 534 i = KillsMask.find_next(i)) {
526 Weights[i].setWeight(RegWeight::Inf); 535 Weights[i].setWeight(RegWeight::Inf);
527 if (PreferReg == i) 536 if (PreferReg == i)
528 AllowOverlap = false; 537 AllowOverlap = false;
529 } 538 }
530 } 539 }
531 540
532 // Print info about physical register availability. 541 // Print info about physical register availability.
533 if (Verbose) { 542 if (Verbose) {
543 Ostream &Str = Ctx->getStrDump();
534 for (SizeT i = 0; i < RegMask.size(); ++i) { 544 for (SizeT i = 0; i < RegMask.size(); ++i) {
535 if (RegMask[i]) { 545 if (RegMask[i]) {
536 Str << Func->getTarget()->getRegName(i, IceType_i32) 546 Str << Func->getTarget()->getRegName(i, IceType_i32)
537 << "(U=" << RegUses[i] << ",F=" << Free[i] 547 << "(U=" << RegUses[i] << ",F=" << Free[i]
538 << ",P=" << PrecoloredUnhandledMask[i] << ") "; 548 << ",P=" << PrecoloredUnhandledMask[i] << ") ";
539 } 549 }
540 } 550 }
541 Str << "\n"; 551 Str << "\n";
542 } 552 }
543 553
544 if (Prefer && (AllowOverlap || Free[PreferReg])) { 554 if (Prefer && (AllowOverlap || Free[PreferReg])) {
545 // First choice: a preferred register that is either free or is 555 // First choice: a preferred register that is either free or is
546 // allowed to overlap with its linked variable. 556 // allowed to overlap with its linked variable.
547 Cur->setRegNumTmp(PreferReg); 557 Cur->setRegNumTmp(PreferReg);
548 if (Verbose) { 558 if (Verbose) {
559 Ostream &Str = Ctx->getStrDump();
549 Str << "Preferring "; 560 Str << "Preferring ";
550 dumpLiveRange(Cur, Func); 561 dumpLiveRange(Cur, Func);
551 Str << "\n"; 562 Str << "\n";
552 } 563 }
553 assert(RegUses[PreferReg] >= 0); 564 assert(RegUses[PreferReg] >= 0);
554 ++RegUses[PreferReg]; 565 ++RegUses[PreferReg];
555 Active.push_back(Cur); 566 Active.push_back(Cur);
556 } else if (Free.any()) { 567 } else if (Free.any()) {
557 // Second choice: any free register. TODO: After explicit 568 // Second choice: any free register. TODO: After explicit
558 // affinity is considered, is there a strategy better than just 569 // affinity is considered, is there a strategy better than just
559 // picking the lowest-numbered available register? 570 // picking the lowest-numbered available register?
560 int32_t RegNum = Free.find_first(); 571 int32_t RegNum = Free.find_first();
561 Cur->setRegNumTmp(RegNum); 572 Cur->setRegNumTmp(RegNum);
562 if (Verbose) { 573 if (Verbose) {
574 Ostream &Str = Ctx->getStrDump();
563 Str << "Allocating "; 575 Str << "Allocating ";
564 dumpLiveRange(Cur, Func); 576 dumpLiveRange(Cur, Func);
565 Str << "\n"; 577 Str << "\n";
566 } 578 }
567 assert(RegUses[RegNum] >= 0); 579 assert(RegUses[RegNum] >= 0);
568 ++RegUses[RegNum]; 580 ++RegUses[RegNum];
569 Active.push_back(Cur); 581 Active.push_back(Cur);
570 } else { 582 } else {
571 // Fallback: there are no free registers, so we look for the 583 // Fallback: there are no free registers, so we look for the
572 // lowest-weight register and see if Cur has higher weight. 584 // lowest-weight register and see if Cur has higher weight.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 "infinite-weight live range"); 618 "infinite-weight live range");
607 } 619 }
608 } else { 620 } else {
609 // Evict all live ranges in Active that register number 621 // Evict all live ranges in Active that register number
610 // MinWeightIndex is assigned to. 622 // MinWeightIndex is assigned to.
611 for (SizeT I = Active.size(); I > 0; --I) { 623 for (SizeT I = Active.size(); I > 0; --I) {
612 const SizeT Index = I - 1; 624 const SizeT Index = I - 1;
613 Variable *Item = Active[Index]; 625 Variable *Item = Active[Index];
614 if (Item->getRegNumTmp() == MinWeightIndex) { 626 if (Item->getRegNumTmp() == MinWeightIndex) {
615 if (Verbose) { 627 if (Verbose) {
628 Ostream &Str = Ctx->getStrDump();
616 Str << "Evicting "; 629 Str << "Evicting ";
617 dumpLiveRange(Item, Func); 630 dumpLiveRange(Item, Func);
618 Str << "\n"; 631 Str << "\n";
619 } 632 }
620 --RegUses[MinWeightIndex]; 633 --RegUses[MinWeightIndex];
621 assert(RegUses[MinWeightIndex] >= 0); 634 assert(RegUses[MinWeightIndex] >= 0);
622 Item->setRegNumTmp(Variable::NoRegister); 635 Item->setRegNumTmp(Variable::NoRegister);
623 moveItem(Active, Index, Handled); 636 moveItem(Active, Index, Handled);
624 } 637 }
625 } 638 }
626 // Do the same for Inactive. 639 // Do the same for Inactive.
627 for (SizeT I = Inactive.size(); I > 0; --I) { 640 for (SizeT I = Inactive.size(); I > 0; --I) {
628 const SizeT Index = I - 1; 641 const SizeT Index = I - 1;
629 Variable *Item = Inactive[Index]; 642 Variable *Item = Inactive[Index];
630 // Note: The Item->rangeOverlaps(Cur) clause is not part of the 643 // Note: The Item->rangeOverlaps(Cur) clause is not part of the
631 // description of AssignMemLoc() in the original paper. But 644 // description of AssignMemLoc() in the original paper. But
632 // there doesn't seem to be any need to evict an inactive 645 // there doesn't seem to be any need to evict an inactive
633 // live range that doesn't overlap with the live range 646 // live range that doesn't overlap with the live range
634 // currently being considered. It's especially bad if we 647 // currently being considered. It's especially bad if we
635 // would end up evicting an infinite-weight but 648 // would end up evicting an infinite-weight but
636 // currently-inactive live range. The most common situation 649 // currently-inactive live range. The most common situation
637 // for this would be a scratch register kill set for call 650 // for this would be a scratch register kill set for call
638 // instructions. 651 // instructions.
639 if (Item->getRegNumTmp() == MinWeightIndex && 652 if (Item->getRegNumTmp() == MinWeightIndex &&
640 Item->rangeOverlaps(Cur)) { 653 Item->rangeOverlaps(Cur)) {
641 if (Verbose) { 654 if (Verbose) {
655 Ostream &Str = Ctx->getStrDump();
642 Str << "Evicting "; 656 Str << "Evicting ";
643 dumpLiveRange(Item, Func); 657 dumpLiveRange(Item, Func);
644 Str << "\n"; 658 Str << "\n";
645 } 659 }
646 Item->setRegNumTmp(Variable::NoRegister); 660 Item->setRegNumTmp(Variable::NoRegister);
647 moveItem(Inactive, Index, Handled); 661 moveItem(Inactive, Index, Handled);
648 } 662 }
649 } 663 }
650 // Assign the register to Cur. 664 // Assign the register to Cur.
651 Cur->setRegNumTmp(MinWeightIndex); 665 Cur->setRegNumTmp(MinWeightIndex);
652 assert(RegUses[MinWeightIndex] >= 0); 666 assert(RegUses[MinWeightIndex] >= 0);
653 ++RegUses[MinWeightIndex]; 667 ++RegUses[MinWeightIndex];
654 Active.push_back(Cur); 668 Active.push_back(Cur);
655 if (Verbose) { 669 if (Verbose) {
670 Ostream &Str = Ctx->getStrDump();
656 Str << "Allocating "; 671 Str << "Allocating ";
657 dumpLiveRange(Cur, Func); 672 dumpLiveRange(Cur, Func);
658 Str << "\n"; 673 Str << "\n";
659 } 674 }
660 } 675 }
661 } 676 }
662 dump(Func); 677 dump(Func);
663 } 678 }
664 // Move anything Active or Inactive to Handled for easier handling. 679 // Move anything Active or Inactive to Handled for easier handling.
665 for (Variable *I : Active) 680 for (Variable *I : Active)
(...skipping 13 matching lines...) Expand all
679 // Finish up by assigning RegNumTmp->RegNum (or a random permutation 694 // Finish up by assigning RegNumTmp->RegNum (or a random permutation
680 // thereof) for each Variable. 695 // thereof) for each Variable.
681 for (Variable *Item : Handled) { 696 for (Variable *Item : Handled) {
682 int32_t RegNum = Item->getRegNumTmp(); 697 int32_t RegNum = Item->getRegNumTmp();
683 int32_t AssignedRegNum = RegNum; 698 int32_t AssignedRegNum = RegNum;
684 699
685 if (Randomized && Item->hasRegTmp() && !Item->hasReg()) { 700 if (Randomized && Item->hasRegTmp() && !Item->hasReg()) {
686 AssignedRegNum = Permutation[RegNum]; 701 AssignedRegNum = Permutation[RegNum];
687 } 702 }
688 if (Verbose) { 703 if (Verbose) {
704 Ostream &Str = Ctx->getStrDump();
689 if (!Item->hasRegTmp()) { 705 if (!Item->hasRegTmp()) {
690 Str << "Not assigning "; 706 Str << "Not assigning ";
691 Item->dump(Func); 707 Item->dump(Func);
692 Str << "\n"; 708 Str << "\n";
693 } else { 709 } else {
694 Str << (AssignedRegNum == Item->getRegNum() ? "Reassigning " 710 Str << (AssignedRegNum == Item->getRegNum() ? "Reassigning "
695 : "Assigning ") 711 : "Assigning ")
696 << Func->getTarget()->getRegName(AssignedRegNum, IceType_i32) 712 << Func->getTarget()->getRegName(AssignedRegNum, IceType_i32)
697 << "(r" << AssignedRegNum << ") to "; 713 << "(r" << AssignedRegNum << ") to ";
698 Item->dump(Func); 714 Item->dump(Func);
699 Str << "\n"; 715 Str << "\n";
700 } 716 }
701 } 717 }
702 Item->setRegNum(AssignedRegNum); 718 Item->setRegNum(AssignedRegNum);
703 } 719 }
704 720
705 // TODO: Consider running register allocation one more time, with 721 // TODO: Consider running register allocation one more time, with
706 // infinite registers, for two reasons. First, evicted live ranges 722 // infinite registers, for two reasons. First, evicted live ranges
707 // get a second chance for a register. Second, it allows coalescing 723 // get a second chance for a register. Second, it allows coalescing
708 // of stack slots. If there is no time budget for the second 724 // of stack slots. If there is no time budget for the second
709 // register allocation run, each unallocated variable just gets its 725 // register allocation run, each unallocated variable just gets its
710 // own slot. 726 // own slot.
711 // 727 //
712 // Another idea for coalescing stack slots is to initialize the 728 // Another idea for coalescing stack slots is to initialize the
713 // Unhandled list with just the unallocated variables, saving time 729 // Unhandled list with just the unallocated variables, saving time
714 // but not offering second-chance opportunities. 730 // but not offering second-chance opportunities.
731
732 if (Verbose)
733 Ctx->unlockStr();
715 } 734 }
716 735
717 // ======================== Dump routines ======================== // 736 // ======================== Dump routines ======================== //
718 737
719 void LinearScan::dump(Cfg *Func) const { 738 void LinearScan::dump(Cfg *Func) const {
720 if (!ALLOW_DUMP) 739 if (!ALLOW_DUMP)
721 return; 740 return;
722 Ostream &Str = Func->getContext()->getStrDump();
723 if (!Func->getContext()->isVerbose(IceV_LinearScan)) 741 if (!Func->getContext()->isVerbose(IceV_LinearScan))
724 return; 742 return;
743 Ostream &Str = Func->getContext()->getStrDump();
725 Func->resetCurrentNode(); 744 Func->resetCurrentNode();
726 Str << "**** Current regalloc state:\n"; 745 Str << "**** Current regalloc state:\n";
727 Str << "++++++ Handled:\n"; 746 Str << "++++++ Handled:\n";
728 for (const Variable *Item : Handled) { 747 for (const Variable *Item : Handled) {
729 dumpLiveRange(Item, Func); 748 dumpLiveRange(Item, Func);
730 Str << "\n"; 749 Str << "\n";
731 } 750 }
732 Str << "++++++ Unhandled:\n"; 751 Str << "++++++ Unhandled:\n";
733 for (const Variable *Item : reverse_range(Unhandled)) { 752 for (const Variable *Item : reverse_range(Unhandled)) {
734 dumpLiveRange(Item, Func); 753 dumpLiveRange(Item, Func);
735 Str << "\n"; 754 Str << "\n";
736 } 755 }
737 Str << "++++++ Active:\n"; 756 Str << "++++++ Active:\n";
738 for (const Variable *Item : Active) { 757 for (const Variable *Item : Active) {
739 dumpLiveRange(Item, Func); 758 dumpLiveRange(Item, Func);
740 Str << "\n"; 759 Str << "\n";
741 } 760 }
742 Str << "++++++ Inactive:\n"; 761 Str << "++++++ Inactive:\n";
743 for (const Variable *Item : Inactive) { 762 for (const Variable *Item : Inactive) {
744 dumpLiveRange(Item, Func); 763 dumpLiveRange(Item, Func);
745 Str << "\n"; 764 Str << "\n";
746 } 765 }
747 } 766 }
748 767
749 } // end of namespace Ice 768 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceOperand.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698