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

Side by Side Diff: src/IceRegAlloc.cpp

Issue 1319203005: Subzero. Changes the Register Allocator so that it is aware of register (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments. Created 5 years, 3 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
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 /// \file 10 /// \file
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« src/IceRegAlloc.h ('K') | « src/IceRegAlloc.h ('k') | src/IceTargetLowering.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698