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

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