| 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 |