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

Side by Side Diff: src/IceRegAlloc.cpp

Issue 1392383003: Subzero: Consider all instruction variables for register preference. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 2 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 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 void LinearScan::findRegisterPreference(IterationState &Iter) { 486 void LinearScan::findRegisterPreference(IterationState &Iter) {
487 Iter.Prefer = nullptr; 487 Iter.Prefer = nullptr;
488 Iter.PreferReg = Variable::NoRegister; 488 Iter.PreferReg = Variable::NoRegister;
489 Iter.AllowOverlap = false; 489 Iter.AllowOverlap = false;
490 490
491 if (FindPreference) { 491 if (FindPreference) {
492 VariablesMetadata *VMetadata = Func->getVMetadata(); 492 VariablesMetadata *VMetadata = Func->getVMetadata();
493 if (const Inst *DefInst = 493 if (const Inst *DefInst =
494 VMetadata->getFirstDefinitionSingleBlock(Iter.Cur)) { 494 VMetadata->getFirstDefinitionSingleBlock(Iter.Cur)) {
495 assert(DefInst->getDest() == Iter.Cur); 495 assert(DefInst->getDest() == Iter.Cur);
496 bool IsAssign = DefInst->isSimpleAssign(); 496 bool IsAssign = DefInst->isVarAssign();
497 bool IsSingleDef = !VMetadata->isMultiDef(Iter.Cur); 497 bool IsSingleDef = !VMetadata->isMultiDef(Iter.Cur);
498 for (SizeT i = 0; i < DefInst->getSrcSize(); ++i) { 498 FOREACH_VAR_IN_INST(SrcVar, *DefInst) {
499 // TODO(stichnot): Iterate through the actual Variables of the 499 int32_t SrcReg = SrcVar->getRegNumTmp();
500 // instruction, not just the source operands. This could capture Load 500 // Only consider source variables that have (so far) been assigned a
501 // instructions, including address mode optimization, for Prefer (but 501 // register. That register must be one in the RegMask set, e.g. don't
502 // not for AllowOverlap). 502 // try to prefer the stack pointer as a result of the stacksave
503 if (Variable *SrcVar = llvm::dyn_cast<Variable>(DefInst->getSrc(i))) { 503 // intrinsic.
504 int32_t SrcReg = SrcVar->getRegNumTmp(); 504 if (SrcVar->hasRegTmp() && (Iter.RegMask & *RegAliases[SrcReg]).any()) {
John 2015/10/12 15:35:17 this is super hard to read!!! const bool SrcVarRe
Jim Stichnoth 2015/10/12 17:27:31 Done. Note that I want to put the cheap hasRegTmp
John 2015/10/12 20:39:58 Then you can define a static method (in an unnamed
505 // Only consider source variables that have (so far) been assigned a 505 if (FindOverlap && !Iter.Free[SrcReg]) {
506 // register. That register must be one in the RegMask set, e.g. don't 506 // Don't bother trying to enable AllowOverlap if the register is
507 // try to prefer the stack pointer as a result of the stacksave 507 // already free.
508 // intrinsic. 508 Iter.AllowOverlap = IsSingleDef && IsAssign &&
509 if (SrcVar->hasRegTmp() && Iter.RegMask[SrcReg]) { 509 !overlapsDefs(Func, Iter.Cur, SrcVar);
510 if (FindOverlap && !Iter.Free[SrcReg]) { 510 }
511 // Don't bother trying to enable AllowOverlap if the register is 511 if (Iter.AllowOverlap || Iter.Free[SrcReg]) {
512 // already free. 512 Iter.Prefer = SrcVar;
513 Iter.AllowOverlap = IsSingleDef && IsAssign && 513 Iter.PreferReg = SrcReg;
514 !overlapsDefs(Func, Iter.Cur, SrcVar); 514 // Stop looking for a preference after the first valid preference is
515 } 515 // found. One might think that we should look at all instruction
516 if (Iter.AllowOverlap || Iter.Free[SrcReg]) { 516 // variables to find the best <Prefer,AllowOverlap> combination, but
517 Iter.Prefer = SrcVar; 517 // note that AllowOverlap can only be true for a simple assignment
518 Iter.PreferReg = SrcReg; 518 // statement which can have only one source operand, so it's not
519 } 519 // possible for AllowOverlap to be true beyond the first source
520 // operand.
521 break;
520 } 522 }
521 } 523 }
522 } 524 }
523 if (Verbose && Iter.Prefer) { 525 if (Verbose && Iter.Prefer) {
524 Ostream &Str = Ctx->getStrDump(); 526 Ostream &Str = Ctx->getStrDump();
525 Str << "Initial Iter.Prefer="; 527 Str << "Initial Iter.Prefer=";
526 Iter.Prefer->dump(Func); 528 Iter.Prefer->dump(Func);
527 Str << " R=" << Iter.PreferReg 529 Str << " R=" << Iter.PreferReg
528 << " LIVE=" << Iter.Prefer->getLiveRange() 530 << " LIVE=" << Iter.Prefer->getLiveRange()
529 << " Overlap=" << Iter.AllowOverlap << "\n"; 531 << " Overlap=" << Iter.AllowOverlap << "\n";
530 } 532 }
531 } 533 }
532 } 534 }
533 } 535 }
534 536
535 // Remove registers from the Free[] list where an Inactive range overlaps with 537 // Remove registers from the Free[] list where an Inactive range overlaps with
536 // the current range. 538 // the current range.
537 void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) { 539 void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) {
538 for (const Variable *Item : Inactive) { 540 for (const Variable *Item : Inactive) {
539 if (!Item->rangeOverlaps(Iter.Cur)) 541 if (!Item->rangeOverlaps(Iter.Cur))
540 continue; 542 continue;
541 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; 543 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()];
544 // TODO(stichnot): Do this with bitvector ops, not a loop, for efficiency.
John 2015/10/12 15:35:17 this is a simple TODOne: for (int32_t RegAlias =
Jim Stichnoth 2015/10/12 17:27:31 What I mean is, I think it can be changed to somet
542 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; 545 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0;
543 RegAlias = Aliases.find_next(RegAlias)) { 546 RegAlias = Aliases.find_next(RegAlias)) {
544 // Don't assert(Free[RegNum]) because in theory (though probably never in 547 // Don't assert(Free[RegNum]) because in theory (though probably never in
545 // practice) there could be two inactive variables that were marked with 548 // practice) there could be two inactive variables that were marked with
546 // AllowOverlap. 549 // AllowOverlap.
547 Iter.Free[RegAlias] = false; 550 Iter.Free[RegAlias] = false;
548 // Disable AllowOverlap if an Inactive variable, which is not Prefer, 551 // Disable AllowOverlap if an Inactive variable, which is not Prefer,
549 // shares Prefer's register, and has a definition within Cur's live 552 // shares Prefer's register, and has a definition within Cur's live
550 // range. 553 // range.
551 if (Iter.AllowOverlap && Item != Iter.Prefer && 554 if (Iter.AllowOverlap && Item != Iter.Prefer &&
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 } 848 }
846 849
847 findRegisterPreference(Iter); 850 findRegisterPreference(Iter);
848 filterFreeWithInactiveRanges(Iter); 851 filterFreeWithInactiveRanges(Iter);
849 852
850 // Disable AllowOverlap if an Active variable, which is not Prefer, shares 853 // Disable AllowOverlap if an Active variable, which is not Prefer, shares
851 // Prefer's register, and has a definition within Cur's live range. 854 // Prefer's register, and has a definition within Cur's live range.
852 if (Iter.AllowOverlap) { 855 if (Iter.AllowOverlap) {
853 for (const Variable *Item : Active) { 856 for (const Variable *Item : Active) {
854 int32_t RegNum = Item->getRegNumTmp(); 857 int32_t RegNum = Item->getRegNumTmp();
858 // TODO(stichnot): Consider aliases of RegNum. This is probably a
859 // correctness issue.
John 2015/10/12 15:35:17 This is definitively a correctness issue... :(
Jim Stichnoth 2015/10/12 17:27:31 Yeah, I want to address it in the context of the x
855 if (Item != Iter.Prefer && RegNum == Iter.PreferReg && 860 if (Item != Iter.Prefer && RegNum == Iter.PreferReg &&
856 overlapsDefs(Func, Iter.Cur, Item)) { 861 overlapsDefs(Func, Iter.Cur, Item)) {
857 Iter.AllowOverlap = false; 862 Iter.AllowOverlap = false;
858 dumpDisableOverlap(Func, Item, "Active"); 863 dumpDisableOverlap(Func, Item, "Active");
859 } 864 }
860 } 865 }
861 } 866 }
862 867
863 Iter.Weights.resize(Iter.RegMask.size()); 868 Iter.Weights.resize(Iter.RegMask.size());
864 std::fill(Iter.Weights.begin(), Iter.Weights.end(), RegWeight()); 869 std::fill(Iter.Weights.begin(), Iter.Weights.end(), RegWeight());
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 Str << "\n"; 975 Str << "\n";
971 } 976 }
972 Str << "++++++ Inactive:\n"; 977 Str << "++++++ Inactive:\n";
973 for (const Variable *Item : Inactive) { 978 for (const Variable *Item : Inactive) {
974 dumpLiveRange(Item, Func); 979 dumpLiveRange(Item, Func);
975 Str << "\n"; 980 Str << "\n";
976 } 981 }
977 } 982 }
978 983
979 } // end of namespace Ice 984 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698