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

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: Code review changes 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
« no previous file with comments | « src/IceInstX86Base.h ('k') | 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 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 // Only consider source variables that have (so far) been assigned a
500 // instruction, not just the source operands. This could capture Load 500 // register. That register must be one in the RegMask set, e.g. don't
501 // instructions, including address mode optimization, for Prefer (but 501 // try to prefer the stack pointer as a result of the stacksave
502 // not for AllowOverlap). 502 // intrinsic.
503 if (Variable *SrcVar = llvm::dyn_cast<Variable>(DefInst->getSrc(i))) { 503 if (SrcVar->hasRegTmp()) {
504 int32_t SrcReg = SrcVar->getRegNumTmp(); 504 const int32_t SrcReg = SrcVar->getRegNumTmp();
505 // Only consider source variables that have (so far) been assigned a 505 const bool IsAliasAvailable =
506 // register. That register must be one in the RegMask set, e.g. don't 506 (Iter.RegMask & *RegAliases[SrcReg]).any();
507 // try to prefer the stack pointer as a result of the stacksave 507 if (IsAliasAvailable) {
508 // intrinsic.
509 if (SrcVar->hasRegTmp() && Iter.RegMask[SrcReg]) {
510 if (FindOverlap && !Iter.Free[SrcReg]) { 508 if (FindOverlap && !Iter.Free[SrcReg]) {
511 // Don't bother trying to enable AllowOverlap if the register is 509 // Don't bother trying to enable AllowOverlap if the register is
512 // already free. 510 // already free.
513 Iter.AllowOverlap = IsSingleDef && IsAssign && 511 Iter.AllowOverlap = IsSingleDef && IsAssign &&
514 !overlapsDefs(Func, Iter.Cur, SrcVar); 512 !overlapsDefs(Func, Iter.Cur, SrcVar);
515 } 513 }
516 if (Iter.AllowOverlap || Iter.Free[SrcReg]) { 514 if (Iter.AllowOverlap || Iter.Free[SrcReg]) {
517 Iter.Prefer = SrcVar; 515 Iter.Prefer = SrcVar;
518 Iter.PreferReg = SrcReg; 516 Iter.PreferReg = SrcReg;
517 // Stop looking for a preference after the first valid preference
518 // is found. One might think that we should look at all
519 // instruction variables to find the best <Prefer,AllowOverlap>
520 // combination, but note that AllowOverlap can only be true for a
521 // simple assignment statement which can have only one source
522 // operand, so it's not possible for AllowOverlap to be true
523 // beyond the first source operand.
524 FOREACH_VAR_IN_INST_BREAK;
519 } 525 }
520 } 526 }
521 } 527 }
522 } 528 }
523 if (Verbose && Iter.Prefer) { 529 if (Verbose && Iter.Prefer) {
524 Ostream &Str = Ctx->getStrDump(); 530 Ostream &Str = Ctx->getStrDump();
525 Str << "Initial Iter.Prefer="; 531 Str << "Initial Iter.Prefer=";
526 Iter.Prefer->dump(Func); 532 Iter.Prefer->dump(Func);
527 Str << " R=" << Iter.PreferReg 533 Str << " R=" << Iter.PreferReg
528 << " LIVE=" << Iter.Prefer->getLiveRange() 534 << " LIVE=" << Iter.Prefer->getLiveRange()
529 << " Overlap=" << Iter.AllowOverlap << "\n"; 535 << " Overlap=" << Iter.AllowOverlap << "\n";
530 } 536 }
531 } 537 }
532 } 538 }
533 } 539 }
534 540
535 // Remove registers from the Free[] list where an Inactive range overlaps with 541 // Remove registers from the Free[] list where an Inactive range overlaps with
536 // the current range. 542 // the current range.
537 void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) { 543 void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) {
538 for (const Variable *Item : Inactive) { 544 for (const Variable *Item : Inactive) {
539 if (!Item->rangeOverlaps(Iter.Cur)) 545 if (!Item->rangeOverlaps(Iter.Cur))
540 continue; 546 continue;
541 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; 547 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()];
548 // TODO(stichnot): Do this with bitvector ops, not a loop, for efficiency.
542 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; 549 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0;
543 RegAlias = Aliases.find_next(RegAlias)) { 550 RegAlias = Aliases.find_next(RegAlias)) {
544 // Don't assert(Free[RegNum]) because in theory (though probably never in 551 // Don't assert(Free[RegNum]) because in theory (though probably never in
545 // practice) there could be two inactive variables that were marked with 552 // practice) there could be two inactive variables that were marked with
546 // AllowOverlap. 553 // AllowOverlap.
547 Iter.Free[RegAlias] = false; 554 Iter.Free[RegAlias] = false;
548 // Disable AllowOverlap if an Inactive variable, which is not Prefer, 555 // Disable AllowOverlap if an Inactive variable, which is not Prefer,
549 // shares Prefer's register, and has a definition within Cur's live 556 // shares Prefer's register, and has a definition within Cur's live
550 // range. 557 // range.
551 if (Iter.AllowOverlap && Item != Iter.Prefer && 558 if (Iter.AllowOverlap && Item != Iter.Prefer &&
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 } 852 }
846 853
847 findRegisterPreference(Iter); 854 findRegisterPreference(Iter);
848 filterFreeWithInactiveRanges(Iter); 855 filterFreeWithInactiveRanges(Iter);
849 856
850 // Disable AllowOverlap if an Active variable, which is not Prefer, shares 857 // Disable AllowOverlap if an Active variable, which is not Prefer, shares
851 // Prefer's register, and has a definition within Cur's live range. 858 // Prefer's register, and has a definition within Cur's live range.
852 if (Iter.AllowOverlap) { 859 if (Iter.AllowOverlap) {
853 for (const Variable *Item : Active) { 860 for (const Variable *Item : Active) {
854 int32_t RegNum = Item->getRegNumTmp(); 861 int32_t RegNum = Item->getRegNumTmp();
862 // TODO(stichnot): Consider aliases of RegNum. This is probably a
863 // correctness issue.
855 if (Item != Iter.Prefer && RegNum == Iter.PreferReg && 864 if (Item != Iter.Prefer && RegNum == Iter.PreferReg &&
856 overlapsDefs(Func, Iter.Cur, Item)) { 865 overlapsDefs(Func, Iter.Cur, Item)) {
857 Iter.AllowOverlap = false; 866 Iter.AllowOverlap = false;
858 dumpDisableOverlap(Func, Item, "Active"); 867 dumpDisableOverlap(Func, Item, "Active");
859 } 868 }
860 } 869 }
861 } 870 }
862 871
863 Iter.Weights.resize(Iter.RegMask.size()); 872 Iter.Weights.resize(Iter.RegMask.size());
864 std::fill(Iter.Weights.begin(), Iter.Weights.end(), RegWeight()); 873 std::fill(Iter.Weights.begin(), Iter.Weights.end(), RegWeight());
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 Str << "\n"; 979 Str << "\n";
971 } 980 }
972 Str << "++++++ Inactive:\n"; 981 Str << "++++++ Inactive:\n";
973 for (const Variable *Item : Inactive) { 982 for (const Variable *Item : Inactive) {
974 dumpLiveRange(Item, Func); 983 dumpLiveRange(Item, Func);
975 Str << "\n"; 984 Str << "\n";
976 } 985 }
977 } 986 }
978 987
979 } // end of namespace Ice 988 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstX86Base.h ('k') | src/IceTargetLowering.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698