OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |