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

Side by Side Diff: src/IceRegAlloc.cpp

Issue 1448773002: Subzero: Do some cleanup on the regalloc code. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix conditional Created 5 years, 1 month 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 | « no previous file | src/IceTargetLowering.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 /// \file 10 /// \file
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 if (Item->getLiveRange().overlapsInst(Def->getNumber(), UseTrimmed)) 42 if (Item->getLiveRange().overlapsInst(Def->getNumber(), UseTrimmed))
43 return true; 43 return true;
44 } 44 }
45 return false; 45 return false;
46 } 46 }
47 47
48 void dumpDisableOverlap(const Cfg *Func, const Variable *Var, 48 void dumpDisableOverlap(const Cfg *Func, const Variable *Var,
49 const char *Reason) { 49 const char *Reason) {
50 if (!BuildDefs::dump()) 50 if (!BuildDefs::dump())
51 return; 51 return;
52 if (Func->isVerbose(IceV_LinearScan)) { 52 if (!Func->isVerbose(IceV_LinearScan))
53 VariablesMetadata *VMetadata = Func->getVMetadata(); 53 return;
54 Ostream &Str = Func->getContext()->getStrDump(); 54
55 Str << "Disabling Overlap due to " << Reason << " " << *Var 55 VariablesMetadata *VMetadata = Func->getVMetadata();
56 << " LIVE=" << Var->getLiveRange() << " Defs="; 56 Ostream &Str = Func->getContext()->getStrDump();
57 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var)) 57 Str << "Disabling Overlap due to " << Reason << " " << *Var
58 Str << FirstDef->getNumber(); 58 << " LIVE=" << Var->getLiveRange() << " Defs=";
59 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var); 59 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var))
60 for (size_t i = 0; i < Defs.size(); ++i) { 60 Str << FirstDef->getNumber();
61 Str << "," << Defs[i]->getNumber(); 61 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var);
62 } 62 for (size_t i = 0; i < Defs.size(); ++i) {
63 Str << "\n"; 63 Str << "," << Defs[i]->getNumber();
64 } 64 }
65 Str << "\n";
65 } 66 }
66 67
67 void dumpLiveRange(const Variable *Var, const Cfg *Func) { 68 void dumpLiveRange(const Variable *Var, const Cfg *Func) {
68 if (!BuildDefs::dump()) 69 if (!BuildDefs::dump())
69 return; 70 return;
70 Ostream &Str = Func->getContext()->getStrDump(); 71 Ostream &Str = Func->getContext()->getStrDump();
71 char buf[30]; 72 char buf[30];
72 snprintf(buf, llvm::array_lengthof(buf), "%2d", Var->getRegNumTmp()); 73 snprintf(buf, llvm::array_lengthof(buf), "%2d", Var->getRegNumTmp());
73 Str << "R=" << buf << " V="; 74 Str << "R=" << buf << " V=";
74 Var->dump(Func); 75 Var->dump(Func);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 << ", variable " << Var->getName(Func) << "\n"; 154 << ", variable " << Var->getName(Func) << "\n";
154 } 155 }
155 for (SizeT VarNum : UsesBeforeDefs) { 156 for (SizeT VarNum : UsesBeforeDefs) {
156 Variable *Var = Vars[VarNum]; 157 Variable *Var = Vars[VarNum];
157 Str << "LR use before def, instruction " << LREnd[VarNum] << ", variable " 158 Str << "LR use before def, instruction " << LREnd[VarNum] << ", variable "
158 << Var->getName(Func) << "\n"; 159 << Var->getName(Func) << "\n";
159 } 160 }
160 return false; 161 return false;
161 } 162 }
162 163
163 // Prepare for very simple register allocation of only infinite-weight 164 // Prepare for very simple register allocation of only infinite-weight Variables
164 // Variables while respecting pre-colored Variables. Some properties we take 165 // while respecting pre-colored Variables. Some properties we take advantage of:
165 // advantage of:
166 // 166 //
167 // * Live ranges of interest consist of a single segment. 167 // * Live ranges of interest consist of a single segment.
168 // 168 //
169 // * Live ranges of interest never span a call instruction. 169 // * Live ranges of interest never span a call instruction.
170 // 170 //
171 // * Phi instructions are not considered because either phis have already been 171 // * Phi instructions are not considered because either phis have already been
172 // lowered, or they don't contain any pre-colored or infinite-weight 172 // lowered, or they don't contain any pre-colored or infinite-weight
173 // Variables. 173 // Variables.
174 // 174 //
175 // * We don't need to renumber instructions before computing live ranges 175 // * We don't need to renumber instructions before computing live ranges because
176 // because all the high-level ICE instructions are deleted prior to lowering, 176 // all the high-level ICE instructions are deleted prior to lowering, and the
177 // and the low-level instructions are added in monotonically increasing order. 177 // low-level instructions are added in monotonically increasing order.
178 // 178 //
179 // * There are no opportunities for register preference or allowing overlap. 179 // * There are no opportunities for register preference or allowing overlap.
180 // 180 //
181 // Some properties we aren't (yet) taking advantage of: 181 // Some properties we aren't (yet) taking advantage of:
182 // 182 //
183 // * Because live ranges are a single segment, the Inactive set will always be 183 // * Because live ranges are a single segment, the Inactive set will always be
184 // empty, and the live range trimming operation is unnecessary. 184 // empty, and the live range trimming operation is unnecessary.
185 // 185 //
186 // * Calculating overlap of single-segment live ranges could be optimized a 186 // * Calculating overlap of single-segment live ranges could be optimized a bit.
187 // bit.
188 void LinearScan::initForInfOnly() { 187 void LinearScan::initForInfOnly() {
189 TimerMarker T(TimerStack::TT_initUnhandled, Func); 188 TimerMarker T(TimerStack::TT_initUnhandled, Func);
190 FindPreference = false; 189 FindPreference = false;
191 FindOverlap = false; 190 FindOverlap = false;
192 SizeT NumVars = 0; 191 SizeT NumVars = 0;
193 const VarList &Vars = Func->getVariables(); 192 const VarList &Vars = Func->getVariables();
194 193
195 // Iterate across all instructions and record the begin and end of the live 194 // Iterate across all instructions and record the begin and end of the live
196 // range for each variable that is pre-colored or infinite weight. 195 // range for each variable that is pre-colored or infinite weight.
197 CfgVector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel); 196 CfgVector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel);
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 std::sort(UnhandledPrecolored.rbegin(), UnhandledPrecolored.rend(), 342 std::sort(UnhandledPrecolored.rbegin(), UnhandledPrecolored.rend(),
344 CompareRanges); 343 CompareRanges);
345 344
346 Handled.reserve(Unhandled.size()); 345 Handled.reserve(Unhandled.size());
347 Inactive.reserve(Unhandled.size()); 346 Inactive.reserve(Unhandled.size());
348 Active.reserve(Unhandled.size()); 347 Active.reserve(Unhandled.size());
349 Evicted.reserve(Unhandled.size()); 348 Evicted.reserve(Unhandled.size());
350 } 349 }
351 350
352 // This is called when Cur must be allocated a register but no registers are 351 // This is called when Cur must be allocated a register but no registers are
353 // available across Cur's live range. To handle this, we find a register that 352 // available across Cur's live range. To handle this, we find a register that is
354 // is not explicitly used during Cur's live range, spill that register to a 353 // not explicitly used during Cur's live range, spill that register to a stack
355 // stack location right before Cur's live range begins, and fill (reload) the 354 // location right before Cur's live range begins, and fill (reload) the register
356 // register from the stack location right after Cur's live range ends. 355 // from the stack location right after Cur's live range ends.
357 void LinearScan::addSpillFill(IterationState &Iter) { 356 void LinearScan::addSpillFill(IterationState &Iter) {
358 // Identify the actual instructions that begin and end Iter.Cur's live range. 357 // Identify the actual instructions that begin and end Iter.Cur's live range.
359 // Iterate through Iter.Cur's node's instruction list until we find the actual 358 // Iterate through Iter.Cur's node's instruction list until we find the actual
360 // instructions with instruction numbers corresponding to Iter.Cur's recorded 359 // instructions with instruction numbers corresponding to Iter.Cur's recorded
361 // live range endpoints. This sounds inefficient but shouldn't be a problem 360 // live range endpoints. This sounds inefficient but shouldn't be a problem
362 // in practice because: 361 // in practice because:
363 // (1) This function is almost never called in practice. 362 // (1) This function is almost never called in practice.
364 // (2) Since this register over-subscription problem happens only for 363 // (2) Since this register over-subscription problem happens only for
365 // phi-lowered instructions, the number of instructions in the node is 364 // phi-lowered instructions, the number of instructions in the node is
366 // proportional to the number of phi instructions in the original node, 365 // proportional to the number of phi instructions in the original node,
(...skipping 11 matching lines...) Expand all
378 InstList::iterator SpillPoint = Insts.end(); 377 InstList::iterator SpillPoint = Insts.end();
379 InstList::iterator FillPoint = Insts.end(); 378 InstList::iterator FillPoint = Insts.end();
380 // Stop searching after we have found both the SpillPoint and the FillPoint. 379 // Stop searching after we have found both the SpillPoint and the FillPoint.
381 for (auto I = Insts.begin(), E = Insts.end(); 380 for (auto I = Insts.begin(), E = Insts.end();
382 I != E && (SpillPoint == E || FillPoint == E); ++I) { 381 I != E && (SpillPoint == E || FillPoint == E); ++I) {
383 if (I->getNumber() == Start) 382 if (I->getNumber() == Start)
384 SpillPoint = I; 383 SpillPoint = I;
385 if (I->getNumber() == End) 384 if (I->getNumber() == End)
386 FillPoint = I; 385 FillPoint = I;
387 if (SpillPoint != E) { 386 if (SpillPoint != E) {
388 // Remove from RegMask any physical registers referenced during Cur's 387 // Remove from RegMask any physical registers referenced during Cur's live
389 // live range. Start looking after SpillPoint gets set, i.e. once Cur's 388 // range. Start looking after SpillPoint gets set, i.e. once Cur's live
390 // live range begins. 389 // range begins.
391 FOREACH_VAR_IN_INST(Var, *I) { 390 FOREACH_VAR_IN_INST(Var, *I) {
392 if (!Var->hasRegTmp()) 391 if (!Var->hasRegTmp())
393 continue; 392 continue;
394 const llvm::SmallBitVector &Aliases = *RegAliases[Var->getRegNumTmp()]; 393 const llvm::SmallBitVector &Aliases = *RegAliases[Var->getRegNumTmp()];
395 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; 394 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0;
396 RegAlias = Aliases.find_next(RegAlias)) { 395 RegAlias = Aliases.find_next(RegAlias)) {
397 Iter.RegMask[RegAlias] = false; 396 Iter.RegMask[RegAlias] = false;
398 } 397 }
399 } 398 }
400 } 399 }
401 } 400 }
402 assert(SpillPoint != Insts.end()); 401 assert(SpillPoint != Insts.end());
403 assert(FillPoint != Insts.end()); 402 assert(FillPoint != Insts.end());
404 ++FillPoint; 403 ++FillPoint;
405 // TODO(stichnot): Randomize instead of find_first(). 404 // TODO(stichnot): Randomize instead of find_first().
406 int32_t RegNum = Iter.RegMask.find_first(); 405 int32_t RegNum = Iter.RegMask.find_first();
407 assert(RegNum != -1); 406 assert(RegNum != -1);
408 Iter.Cur->setRegNumTmp(RegNum); 407 Iter.Cur->setRegNumTmp(RegNum);
409 Variable *Preg = Target->getPhysicalRegister(RegNum, Iter.Cur->getType()); 408 Variable *Preg = Target->getPhysicalRegister(RegNum, Iter.Cur->getType());
410 // TODO(stichnot): Add SpillLoc to VariablesMetadata tracking so that 409 // TODO(stichnot): Add SpillLoc to VariablesMetadata tracking so that SpillLoc
411 // SpillLoc is correctly identified as !isMultiBlock(), reducing stack frame 410 // is correctly identified as !isMultiBlock(), reducing stack frame size.
412 // size.
413 Variable *SpillLoc = Func->makeVariable(Iter.Cur->getType()); 411 Variable *SpillLoc = Func->makeVariable(Iter.Cur->getType());
414 // Add "reg=FakeDef;spill=reg" before SpillPoint 412 // Add "reg=FakeDef;spill=reg" before SpillPoint
415 Target->lowerInst(Node, SpillPoint, InstFakeDef::create(Func, Preg)); 413 Target->lowerInst(Node, SpillPoint, InstFakeDef::create(Func, Preg));
416 Target->lowerInst(Node, SpillPoint, InstAssign::create(Func, SpillLoc, Preg)); 414 Target->lowerInst(Node, SpillPoint, InstAssign::create(Func, SpillLoc, Preg));
417 // add "reg=spill;FakeUse(reg)" before FillPoint 415 // add "reg=spill;FakeUse(reg)" before FillPoint
418 Target->lowerInst(Node, FillPoint, InstAssign::create(Func, Preg, SpillLoc)); 416 Target->lowerInst(Node, FillPoint, InstAssign::create(Func, Preg, SpillLoc));
419 Target->lowerInst(Node, FillPoint, InstFakeUse::create(Func, Preg)); 417 Target->lowerInst(Node, FillPoint, InstFakeUse::create(Func, Preg));
420 } 418 }
421 419
422 void LinearScan::handleActiveRangeExpiredOrInactive(const Variable *Cur) { 420 void LinearScan::handleActiveRangeExpiredOrInactive(const Variable *Cur) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; 466 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0;
469 RegAlias = Aliases.find_next(RegAlias)) { 467 RegAlias = Aliases.find_next(RegAlias)) {
470 assert(RegUses[RegAlias] >= 0); 468 assert(RegUses[RegAlias] >= 0);
471 ++RegUses[RegAlias]; 469 ++RegUses[RegAlias];
472 } 470 }
473 } 471 }
474 } 472 }
475 } 473 }
476 474
477 // Infer register preference and allowable overlap. Only form a preference when 475 // Infer register preference and allowable overlap. Only form a preference when
478 // the current Variable has an unambiguous "first" definition. The preference 476 // the current Variable has an unambiguous "first" definition. The preference is
479 // is some source Variable of the defining instruction that either is assigned 477 // some source Variable of the defining instruction that either is assigned a
480 // a register that is currently free, or that is assigned a register that is 478 // register that is currently free, or that is assigned a register that is not
481 // not free but overlap is allowed. Overlap is allowed when the Variable under 479 // free but overlap is allowed. Overlap is allowed when the Variable under
482 // consideration is single-definition, and its definition is a simple 480 // consideration is single-definition, and its definition is a simple assignment
483 // assignment - i.e., the register gets copied/aliased but is never modified. 481 // - i.e., the register gets copied/aliased but is never modified. Furthermore,
484 // Furthermore, overlap is only allowed when preferred Variable definition 482 // overlap is only allowed when preferred Variable definition instructions do
485 // instructions do not appear within the current Variable's live range. 483 // not appear within the current Variable's live range.
486 void LinearScan::findRegisterPreference(IterationState &Iter) { 484 void LinearScan::findRegisterPreference(IterationState &Iter) {
487 Iter.Prefer = nullptr; 485 Iter.Prefer = nullptr;
488 Iter.PreferReg = Variable::NoRegister; 486 Iter.PreferReg = Variable::NoRegister;
489 Iter.AllowOverlap = false; 487 Iter.AllowOverlap = false;
490 488
491 if (FindPreference) { 489 if (!FindPreference)
492 VariablesMetadata *VMetadata = Func->getVMetadata(); 490 return;
493 if (const Inst *DefInst = 491
494 VMetadata->getFirstDefinitionSingleBlock(Iter.Cur)) { 492 VariablesMetadata *VMetadata = Func->getVMetadata();
495 assert(DefInst->getDest() == Iter.Cur); 493 const Inst *DefInst = VMetadata->getFirstDefinitionSingleBlock(Iter.Cur);
496 bool IsAssign = DefInst->isVarAssign(); 494 if (DefInst == nullptr)
497 bool IsSingleDef = !VMetadata->isMultiDef(Iter.Cur); 495 return;
498 FOREACH_VAR_IN_INST(SrcVar, *DefInst) { 496
499 // Only consider source variables that have (so far) been assigned a 497 assert(DefInst->getDest() == Iter.Cur);
500 // register. That register must be one in the RegMask set, e.g. don't 498 const bool IsSingleDefAssign =
501 // try to prefer the stack pointer as a result of the stacksave 499 DefInst->isVarAssign() && !VMetadata->isMultiDef(Iter.Cur);
502 // intrinsic. 500 FOREACH_VAR_IN_INST(SrcVar, *DefInst) {
503 if (SrcVar->hasRegTmp()) { 501 // Only consider source variables that have (so far) been assigned a
504 const llvm::SmallBitVector &Aliases = 502 // register.
505 *RegAliases[SrcVar->getRegNumTmp()]; 503 if (!SrcVar->hasRegTmp())
506 const int32_t SrcReg = (Iter.RegMask & Aliases).find_first(); 504 continue;
507 const bool IsAliasAvailable = (SrcReg != -1); 505
508 if (IsAliasAvailable) { 506 // That register must be one in the RegMask set, e.g. don't try to prefer
509 if (FindOverlap && !Iter.Free[SrcReg]) { 507 // the stack pointer as a result of the stacksave intrinsic.
510 // Don't bother trying to enable AllowOverlap if the register is 508 const llvm::SmallBitVector &Aliases = *RegAliases[SrcVar->getRegNumTmp()];
511 // already free. 509 const int32_t SrcReg = (Iter.RegMask & Aliases).find_first();
512 Iter.AllowOverlap = IsSingleDef && IsAssign && 510 if (SrcReg == -1)
513 !overlapsDefs(Func, Iter.Cur, SrcVar); 511 continue;
514 } 512
515 if (Iter.AllowOverlap || Iter.Free[SrcReg]) { 513 if (FindOverlap && IsSingleDefAssign && !Iter.Free[SrcReg]) {
516 Iter.Prefer = SrcVar; 514 // Don't bother trying to enable AllowOverlap if the register is already
517 Iter.PreferReg = SrcReg; 515 // free (hence the test on Iter.Free[SrcReg]).
518 // Stop looking for a preference after the first valid preference 516 Iter.AllowOverlap = !overlapsDefs(Func, Iter.Cur, SrcVar);
519 // is found. One might think that we should look at all
520 // instruction variables to find the best <Prefer,AllowOverlap>
521 // combination, but note that AllowOverlap can only be true for a
522 // simple assignment statement which can have only one source
523 // operand, so it's not possible for AllowOverlap to be true
524 // beyond the first source operand.
525 FOREACH_VAR_IN_INST_BREAK;
526 }
527 }
528 }
529 }
530 if (Verbose && Iter.Prefer) {
531 Ostream &Str = Ctx->getStrDump();
532 Str << "Initial Iter.Prefer=";
533 Iter.Prefer->dump(Func);
534 Str << " R=" << Iter.PreferReg
535 << " LIVE=" << Iter.Prefer->getLiveRange()
536 << " Overlap=" << Iter.AllowOverlap << "\n";
537 }
538 } 517 }
518 if (Iter.AllowOverlap || Iter.Free[SrcReg]) {
519 Iter.Prefer = SrcVar;
520 Iter.PreferReg = SrcReg;
521 // Stop looking for a preference after the first valid preference is
522 // found. One might think that we should look at all instruction
523 // variables to find the best <Prefer,AllowOverlap> combination, but note
524 // that AllowOverlap can only be true for a simple assignment statement
525 // which can have only one source operand, so it's not possible for
526 // AllowOverlap to be true beyond the first source operand.
527 FOREACH_VAR_IN_INST_BREAK;
528 }
529 }
530 if (BuildDefs::dump() && Verbose && Iter.Prefer) {
531 Ostream &Str = Ctx->getStrDump();
532 Str << "Initial Iter.Prefer=";
533 Iter.Prefer->dump(Func);
534 Str << " R=" << Iter.PreferReg << " LIVE=" << Iter.Prefer->getLiveRange()
535 << " Overlap=" << Iter.AllowOverlap << "\n";
539 } 536 }
540 } 537 }
541 538
542 // Remove registers from the Free[] list where an Inactive range overlaps with 539 // Remove registers from the Free[] list where an Inactive range overlaps with
543 // the current range. 540 // the current range.
544 void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) { 541 void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) {
545 for (const Variable *Item : Inactive) { 542 for (const Variable *Item : Inactive) {
546 if (!Item->rangeOverlaps(Iter.Cur)) 543 if (!Item->rangeOverlaps(Iter.Cur))
547 continue; 544 continue;
548 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; 545 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()];
549 // TODO(stichnot): Do this with bitvector ops, not a loop, for efficiency. 546 // TODO(stichnot): Do this with bitvector ops, not a loop, for efficiency.
550 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; 547 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0;
551 RegAlias = Aliases.find_next(RegAlias)) { 548 RegAlias = Aliases.find_next(RegAlias)) {
552 // Don't assert(Free[RegNum]) because in theory (though probably never in 549 // Don't assert(Free[RegNum]) because in theory (though probably never in
553 // practice) there could be two inactive variables that were marked with 550 // practice) there could be two inactive variables that were marked with
554 // AllowOverlap. 551 // AllowOverlap.
555 Iter.Free[RegAlias] = false; 552 Iter.Free[RegAlias] = false;
556 // Disable AllowOverlap if an Inactive variable, which is not Prefer, 553 // Disable AllowOverlap if an Inactive variable, which is not Prefer,
557 // shares Prefer's register, and has a definition within Cur's live 554 // shares Prefer's register, and has a definition within Cur's live range.
558 // range.
559 if (Iter.AllowOverlap && Item != Iter.Prefer && 555 if (Iter.AllowOverlap && Item != Iter.Prefer &&
560 RegAlias == Iter.PreferReg && overlapsDefs(Func, Iter.Cur, Item)) { 556 RegAlias == Iter.PreferReg && overlapsDefs(Func, Iter.Cur, Item)) {
561 Iter.AllowOverlap = false; 557 Iter.AllowOverlap = false;
562 dumpDisableOverlap(Func, Item, "Inactive"); 558 dumpDisableOverlap(Func, Item, "Inactive");
563 } 559 }
564 } 560 }
565 } 561 }
566 } 562 }
567 563
568 // Remove registers from the Free[] list where an Unhandled pre-colored range 564 // Remove registers from the Free[] list where an Unhandled pre-colored range
569 // overlaps with the current range, and set those registers to infinite weight 565 // overlaps with the current range, and set those registers to infinite weight
570 // so that they aren't candidates for eviction. Cur->rangeEndsBefore(Item) is 566 // so that they aren't candidates for eviction. Cur->rangeEndsBefore(Item) is an
571 // an early exit check that turns a guaranteed O(N^2) algorithm into expected 567 // early exit check that turns a guaranteed O(N^2) algorithm into expected
572 // linear complexity. 568 // linear complexity.
573 void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) { 569 void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) {
574 for (Variable *Item : reverse_range(UnhandledPrecolored)) { 570 for (Variable *Item : reverse_range(UnhandledPrecolored)) {
575 assert(Item->hasReg()); 571 assert(Item->hasReg());
576 if (Iter.Cur->rangeEndsBefore(Item)) 572 if (Iter.Cur->rangeEndsBefore(Item))
577 break; 573 break;
578 if (Item->rangeOverlaps(Iter.Cur)) { 574 if (!Item->rangeOverlaps(Iter.Cur))
579 const llvm::SmallBitVector &Aliases = 575 continue;
580 *RegAliases[Item->getRegNum()]; // Note: not getRegNumTmp() 576 const llvm::SmallBitVector &Aliases =
581 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; 577 *RegAliases[Item->getRegNum()]; // Note: not getRegNumTmp()
582 RegAlias = Aliases.find_next(RegAlias)) { 578 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0;
583 Iter.Weights[RegAlias].setWeight(RegWeight::Inf); 579 RegAlias = Aliases.find_next(RegAlias)) {
584 Iter.Free[RegAlias] = false; 580 Iter.Weights[RegAlias].setWeight(RegWeight::Inf);
585 Iter.PrecoloredUnhandledMask[RegAlias] = true; 581 Iter.Free[RegAlias] = false;
586 // Disable Iter.AllowOverlap if the preferred register is one of these 582 Iter.PrecoloredUnhandledMask[RegAlias] = true;
587 // pre-colored unhandled overlapping ranges. 583 // Disable Iter.AllowOverlap if the preferred register is one of these
588 if (Iter.AllowOverlap && RegAlias == Iter.PreferReg) { 584 // pre-colored unhandled overlapping ranges.
589 Iter.AllowOverlap = false; 585 if (Iter.AllowOverlap && RegAlias == Iter.PreferReg) {
590 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled"); 586 Iter.AllowOverlap = false;
591 } 587 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled");
592 } 588 }
593 } 589 }
594 } 590 }
595 } 591 }
596 592
597 void LinearScan::allocatePrecoloredRegister(Variable *Cur) { 593 void LinearScan::allocatePrecoloredRegister(Variable *Cur) {
598 int32_t RegNum = Cur->getRegNum(); 594 int32_t RegNum = Cur->getRegNum();
599 // RegNumTmp should have already been set above. 595 // RegNumTmp should have already been set above.
600 assert(Cur->getRegNumTmp() == RegNum); 596 assert(Cur->getRegNumTmp() == RegNum);
601 dumpLiveRangeTrace("Precoloring ", Cur); 597 dumpLiveRangeTrace("Precoloring ", Cur);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 continue; 653 continue;
658 assert(Item->hasRegTmp()); 654 assert(Item->hasRegTmp());
659 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; 655 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()];
660 RegWeight W = Item->getWeight(Func); 656 RegWeight W = Item->getWeight(Func);
661 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; 657 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0;
662 RegAlias = Aliases.find_next(RegAlias)) { 658 RegAlias = Aliases.find_next(RegAlias)) {
663 Iter.Weights[RegAlias].addWeight(W); 659 Iter.Weights[RegAlias].addWeight(W);
664 } 660 }
665 } 661 }
666 662
667 // All the weights are now calculated. Find the register with smallest 663 // All the weights are now calculated. Find the register with smallest weight.
668 // weight.
669 int32_t MinWeightIndex = Iter.RegMask.find_first(); 664 int32_t MinWeightIndex = Iter.RegMask.find_first();
670 // MinWeightIndex must be valid because of the initial RegMask.any() test. 665 // MinWeightIndex must be valid because of the initial RegMask.any() test.
671 assert(MinWeightIndex >= 0); 666 assert(MinWeightIndex >= 0);
672 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) { 667 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) {
673 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex]) 668 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex])
674 MinWeightIndex = i; 669 MinWeightIndex = i;
675 } 670 }
676 671
677 if (Iter.Cur->getWeight(Func) <= Iter.Weights[MinWeightIndex]) { 672 if (Iter.Cur->getWeight(Func) <= Iter.Weights[MinWeightIndex]) {
678 // Cur doesn't have priority over any other live ranges, so don't allocate 673 // Cur doesn't have priority over any other live ranges, so don't allocate
(...skipping 27 matching lines...) Expand all
706 Evicted.push_back(Item); 701 Evicted.push_back(Item);
707 } 702 }
708 } 703 }
709 // Do the same for Inactive. 704 // Do the same for Inactive.
710 for (SizeT I = Inactive.size(); I > 0; --I) { 705 for (SizeT I = Inactive.size(); I > 0; --I) {
711 const SizeT Index = I - 1; 706 const SizeT Index = I - 1;
712 Variable *Item = Inactive[Index]; 707 Variable *Item = Inactive[Index];
713 // Note: The Item->rangeOverlaps(Cur) clause is not part of the 708 // Note: The Item->rangeOverlaps(Cur) clause is not part of the
714 // description of AssignMemLoc() in the original paper. But there doesn't 709 // description of AssignMemLoc() in the original paper. But there doesn't
715 // seem to be any need to evict an inactive live range that doesn't 710 // seem to be any need to evict an inactive live range that doesn't
716 // overlap with the live range currently being considered. It's 711 // overlap with the live range currently being considered. It's especially
717 // especially bad if we would end up evicting an infinite-weight but 712 // bad if we would end up evicting an infinite-weight but
718 // currently-inactive live range. The most common situation for this 713 // currently-inactive live range. The most common situation for this would
719 // would be a scratch register kill set for call instructions. 714 // be a scratch register kill set for call instructions.
720 if (Aliases[Item->getRegNumTmp()] && Item->rangeOverlaps(Iter.Cur)) { 715 if (Aliases[Item->getRegNumTmp()] && Item->rangeOverlaps(Iter.Cur)) {
721 dumpLiveRangeTrace("Evicting I ", Item); 716 dumpLiveRangeTrace("Evicting I ", Item);
722 Item->setRegNumTmp(Variable::NoRegister); 717 Item->setRegNumTmp(Variable::NoRegister);
723 moveItem(Inactive, Index, Handled); 718 moveItem(Inactive, Index, Handled);
724 Evicted.push_back(Item); 719 Evicted.push_back(Item);
725 } 720 }
726 } 721 }
727 // Assign the register to Cur. 722 // Assign the register to Cur.
728 Iter.Cur->setRegNumTmp(MinWeightIndex); 723 Iter.Cur->setRegNumTmp(MinWeightIndex);
729 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; 724 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0;
(...skipping 25 matching lines...) Expand all
755 750
756 // Finish up by setting RegNum = RegNumTmp (or a random permutation thereof) 751 // Finish up by setting RegNum = RegNumTmp (or a random permutation thereof)
757 // for each Variable. 752 // for each Variable.
758 for (Variable *Item : Handled) { 753 for (Variable *Item : Handled) {
759 int32_t RegNum = Item->getRegNumTmp(); 754 int32_t RegNum = Item->getRegNumTmp();
760 int32_t AssignedRegNum = RegNum; 755 int32_t AssignedRegNum = RegNum;
761 756
762 if (Randomized && Item->hasRegTmp() && !Item->hasReg()) { 757 if (Randomized && Item->hasRegTmp() && !Item->hasReg()) {
763 AssignedRegNum = Permutation[RegNum]; 758 AssignedRegNum = Permutation[RegNum];
764 } 759 }
765 if (Verbose) { 760 if (BuildDefs::dump() && Verbose) {
766 Ostream &Str = Ctx->getStrDump(); 761 Ostream &Str = Ctx->getStrDump();
767 if (!Item->hasRegTmp()) { 762 if (!Item->hasRegTmp()) {
768 Str << "Not assigning "; 763 Str << "Not assigning ";
769 Item->dump(Func); 764 Item->dump(Func);
770 Str << "\n"; 765 Str << "\n";
771 } else { 766 } else {
772 Str << (AssignedRegNum == Item->getRegNum() ? "Reassigning " 767 Str << (AssignedRegNum == Item->getRegNum() ? "Reassigning "
773 : "Assigning ") 768 : "Assigning ")
774 << Target->getRegName(AssignedRegNum, IceType_i32) << "(r" 769 << Target->getRegName(AssignedRegNum, IceType_i32) << "(r"
775 << AssignedRegNum << ") to "; 770 << AssignedRegNum << ") to ";
776 Item->dump(Func); 771 Item->dump(Func);
777 Str << "\n"; 772 Str << "\n";
778 } 773 }
779 } 774 }
780 Item->setRegNum(AssignedRegNum); 775 Item->setRegNum(AssignedRegNum);
781 } 776 }
782 } 777 }
783 778
784 // Implements the linear-scan algorithm. Based on "Linear Scan Register 779 // Implements the linear-scan algorithm. Based on "Linear Scan Register
785 // Allocation in the Context of SSA Form and Register Constraints" by Hanspeter 780 // Allocation in the Context of SSA Form and Register Constraints" by Hanspeter
786 // Mössenböck and Michael Pfeiffer, 781 // Mössenböck and Michael Pfeiffer,
787 // ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF. This implementation is 782 // ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF. This implementation is
788 // modified to take affinity into account and allow two interfering variables 783 // modified to take affinity into account and allow two interfering variables to
789 // to share the same register in certain cases. 784 // share the same register in certain cases.
790 // 785 //
791 // Requires running Cfg::liveness(Liveness_Intervals) in preparation. Results 786 // Requires running Cfg::liveness(Liveness_Intervals) in preparation. Results
792 // are assigned to Variable::RegNum for each Variable. 787 // are assigned to Variable::RegNum for each Variable.
793 void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull, 788 void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull,
794 bool Randomized) { 789 bool Randomized) {
795 TimerMarker T(TimerStack::TT_linearScan, Func); 790 TimerMarker T(TimerStack::TT_linearScan, Func);
796 assert(RegMaskFull.any()); // Sanity check 791 assert(RegMaskFull.any()); // Sanity check
797 if (Verbose) 792 if (Verbose)
798 Ctx->lockStr(); 793 Ctx->lockStr();
799 Func->resetCurrentNode(); 794 Func->resetCurrentNode();
800 const size_t NumRegisters = RegMaskFull.size(); 795 const size_t NumRegisters = RegMaskFull.size();
801 llvm::SmallBitVector PreDefinedRegisters(NumRegisters); 796 llvm::SmallBitVector PreDefinedRegisters(NumRegisters);
802 if (Randomized) { 797 if (Randomized) {
803 for (Variable *Var : UnhandledPrecolored) { 798 for (Variable *Var : UnhandledPrecolored) {
804 PreDefinedRegisters[Var->getRegNum()] = true; 799 PreDefinedRegisters[Var->getRegNum()] = true;
805 } 800 }
806 } 801 }
807 802
808 // Build a LiveRange representing the Kills list. 803 // Build a LiveRange representing the Kills list.
809 LiveRange KillsRange(Kills); 804 LiveRange KillsRange(Kills);
810 KillsRange.untrim(); 805 KillsRange.untrim();
811 806
812 // Reset the register use count 807 // Reset the register use count.
813 RegUses.resize(NumRegisters); 808 RegUses.resize(NumRegisters);
814 std::fill(RegUses.begin(), RegUses.end(), 0); 809 std::fill(RegUses.begin(), RegUses.end(), 0);
815 810
816 // Unhandled is already set to all ranges in increasing order of start 811 // Unhandled is already set to all ranges in increasing order of start points.
817 // points.
818 assert(Active.empty()); 812 assert(Active.empty());
819 assert(Inactive.empty()); 813 assert(Inactive.empty());
820 assert(Handled.empty()); 814 assert(Handled.empty());
821 const TargetLowering::RegSetMask RegsInclude = 815 const TargetLowering::RegSetMask RegsInclude =
822 TargetLowering::RegSet_CallerSave; 816 TargetLowering::RegSet_CallerSave;
823 const TargetLowering::RegSetMask RegsExclude = TargetLowering::RegSet_None; 817 const TargetLowering::RegSetMask RegsExclude = TargetLowering::RegSet_None;
824 const llvm::SmallBitVector KillsMask = 818 const llvm::SmallBitVector KillsMask =
825 Target->getRegisterSet(RegsInclude, RegsExclude); 819 Target->getRegisterSet(RegsInclude, RegsExclude);
826 820
827 // Allocate memory once outside the loop 821 // Allocate memory once outside the loop.
828 IterationState Iter; 822 IterationState Iter;
829 Iter.Weights.reserve(NumRegisters); 823 Iter.Weights.reserve(NumRegisters);
830 Iter.PrecoloredUnhandledMask.reserve(NumRegisters); 824 Iter.PrecoloredUnhandledMask.reserve(NumRegisters);
831 825
832 while (!Unhandled.empty()) { 826 while (!Unhandled.empty()) {
833 Iter.Cur = Unhandled.back(); 827 Iter.Cur = Unhandled.back();
834 Unhandled.pop_back(); 828 Unhandled.pop_back();
835 dumpLiveRangeTrace("\nConsidering ", Iter.Cur); 829 dumpLiveRangeTrace("\nConsidering ", Iter.Cur);
836 Iter.RegMask = RegMaskFull & Target->getRegistersForVariable(Iter.Cur); 830 Iter.RegMask = RegMaskFull & Target->getRegistersForVariable(Iter.Cur);
837 KillsRange.trim(Iter.Cur->getLiveRange().getStart()); 831 KillsRange.trim(Iter.Cur->getLiveRange().getStart());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 Iter.Free.reset(KillsMask); 881 Iter.Free.reset(KillsMask);
888 for (int i = KillsMask.find_first(); i != -1; 882 for (int i = KillsMask.find_first(); i != -1;
889 i = KillsMask.find_next(i)) { 883 i = KillsMask.find_next(i)) {
890 Iter.Weights[i].setWeight(RegWeight::Inf); 884 Iter.Weights[i].setWeight(RegWeight::Inf);
891 if (Iter.PreferReg == i) 885 if (Iter.PreferReg == i)
892 Iter.AllowOverlap = false; 886 Iter.AllowOverlap = false;
893 } 887 }
894 } 888 }
895 889
896 // Print info about physical register availability. 890 // Print info about physical register availability.
897 if (Verbose) { 891 if (BuildDefs::dump() && Verbose) {
898 Ostream &Str = Ctx->getStrDump(); 892 Ostream &Str = Ctx->getStrDump();
899 for (SizeT i = 0; i < Iter.RegMask.size(); ++i) { 893 for (SizeT i = 0; i < Iter.RegMask.size(); ++i) {
900 if (Iter.RegMask[i]) { 894 if (Iter.RegMask[i]) {
901 Str << Target->getRegName(i, IceType_i32) << "(U=" << RegUses[i] 895 Str << Target->getRegName(i, IceType_i32) << "(U=" << RegUses[i]
902 << ",F=" << Iter.Free[i] 896 << ",F=" << Iter.Free[i]
903 << ",P=" << Iter.PrecoloredUnhandledMask[i] << ") "; 897 << ",P=" << Iter.PrecoloredUnhandledMask[i] << ") ";
904 } 898 }
905 } 899 }
906 Str << "\n"; 900 Str << "\n";
907 } 901 }
908 902
909 if (Iter.Prefer && (Iter.AllowOverlap || Iter.Free[Iter.PreferReg])) { 903 if (Iter.Prefer && (Iter.AllowOverlap || Iter.Free[Iter.PreferReg])) {
910 // First choice: a preferred register that is either free or is allowed 904 // First choice: a preferred register that is either free or is allowed to
911 // to overlap with its linked variable. 905 // overlap with its linked variable.
912 allocatePreferredRegister(Iter); 906 allocatePreferredRegister(Iter);
913 } else if (Iter.Free.any()) { 907 } else if (Iter.Free.any()) {
914 // Second choice: any free register. 908 // Second choice: any free register.
915 allocateFreeRegister(Iter); 909 allocateFreeRegister(Iter);
916 } else { 910 } else {
917 // Fallback: there are no free registers, so we look for the 911 // Fallback: there are no free registers, so we look for the lowest-weight
918 // lowest-weight register and see if Cur has higher weight. 912 // register and see if Cur has higher weight.
919 handleNoFreeRegisters(Iter); 913 handleNoFreeRegisters(Iter);
920 } 914 }
921 dump(Func); 915 dump(Func);
922 } 916 }
923 917
924 // Move anything Active or Inactive to Handled for easier handling. 918 // Move anything Active or Inactive to Handled for easier handling.
925 Handled.insert(Handled.end(), Active.begin(), Active.end()); 919 Handled.insert(Handled.end(), Active.begin(), Active.end());
926 Active.clear(); 920 Active.clear();
927 Handled.insert(Handled.end(), Inactive.begin(), Inactive.end()); 921 Handled.insert(Handled.end(), Inactive.begin(), Inactive.end());
928 Inactive.clear(); 922 Inactive.clear();
929 dump(Func); 923 dump(Func);
930 924
931 assignFinalRegisters(RegMaskFull, PreDefinedRegisters, Randomized); 925 assignFinalRegisters(RegMaskFull, PreDefinedRegisters, Randomized);
932 926
933 // TODO: Consider running register allocation one more time, with infinite
934 // registers, for two reasons. First, evicted live ranges get a second chance
935 // for a register. Second, it allows coalescing of stack slots. If there is
936 // no time budget for the second register allocation run, each unallocated
937 // variable just gets its own slot.
938 //
939 // Another idea for coalescing stack slots is to initialize the Unhandled
940 // list with just the unallocated variables, saving time but not offering
941 // second-chance opportunities.
942
943 if (Verbose) 927 if (Verbose)
944 Ctx->unlockStr(); 928 Ctx->unlockStr();
945 } 929 }
946 930
947 // ======================== Dump routines ======================== // 931 // ======================== Dump routines ======================== //
948 932
949 void LinearScan::dumpLiveRangeTrace(const char *Label, const Variable *Item) { 933 void LinearScan::dumpLiveRangeTrace(const char *Label, const Variable *Item) {
950 if (!BuildDefs::dump()) 934 if (!BuildDefs::dump())
951 return; 935 return;
952 936
953 if (Verbose) { 937 if (Verbose) {
954 Ostream &Str = Ctx->getStrDump(); 938 Ostream &Str = Ctx->getStrDump();
955 Str << Label; 939 Str << Label;
956 dumpLiveRange(Item, Func); 940 dumpLiveRange(Item, Func);
957 Str << "\n"; 941 Str << "\n";
958 } 942 }
959 } 943 }
960 944
961 void LinearScan::dump(Cfg *Func) const { 945 void LinearScan::dump(Cfg *Func) const {
962 if (!BuildDefs::dump()) 946 if (!BuildDefs::dump())
963 return; 947 return;
964 if (!Func->isVerbose(IceV_LinearScan)) 948 if (!Verbose)
965 return; 949 return;
966 Ostream &Str = Func->getContext()->getStrDump(); 950 Ostream &Str = Func->getContext()->getStrDump();
967 Func->resetCurrentNode(); 951 Func->resetCurrentNode();
968 Str << "**** Current regalloc state:\n"; 952 Str << "**** Current regalloc state:\n";
969 Str << "++++++ Handled:\n"; 953 Str << "++++++ Handled:\n";
970 for (const Variable *Item : Handled) { 954 for (const Variable *Item : Handled) {
971 dumpLiveRange(Item, Func); 955 dumpLiveRange(Item, Func);
972 Str << "\n"; 956 Str << "\n";
973 } 957 }
974 Str << "++++++ Unhandled:\n"; 958 Str << "++++++ Unhandled:\n";
975 for (const Variable *Item : reverse_range(Unhandled)) { 959 for (const Variable *Item : reverse_range(Unhandled)) {
976 dumpLiveRange(Item, Func); 960 dumpLiveRange(Item, Func);
977 Str << "\n"; 961 Str << "\n";
978 } 962 }
979 Str << "++++++ Active:\n"; 963 Str << "++++++ Active:\n";
980 for (const Variable *Item : Active) { 964 for (const Variable *Item : Active) {
981 dumpLiveRange(Item, Func); 965 dumpLiveRange(Item, Func);
982 Str << "\n"; 966 Str << "\n";
983 } 967 }
984 Str << "++++++ Inactive:\n"; 968 Str << "++++++ Inactive:\n";
985 for (const Variable *Item : Inactive) { 969 for (const Variable *Item : Inactive) {
986 dumpLiveRange(Item, Func); 970 dumpLiveRange(Item, Func);
987 Str << "\n"; 971 Str << "\n";
988 } 972 }
989 } 973 }
990 974
991 } // end of namespace Ice 975 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | src/IceTargetLowering.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698