Index: src/IceTargetLowering.cpp |
diff --git a/src/IceTargetLowering.cpp b/src/IceTargetLowering.cpp |
index bd5c11b47e4fd0548a6084bf3a0c75a4516f0f42..2432c00c0daa5b3718ff14f2bfb1c7eda894c5ab 100644 |
--- a/src/IceTargetLowering.cpp |
+++ b/src/IceTargetLowering.cpp |
@@ -138,39 +138,68 @@ void printRegisterSet(Ostream &Str, const llvm::SmallBitVector &Bitset, |
Str << "\n"; |
} |
+// Splits "<class>:<reg>" into "<class>" plus "<reg>". If there is no <class> |
+// component, the result is "" plus "<reg>". |
+void splitToClassAndName(const IceString &RegName, IceString *SplitRegClass, |
+ IceString *SplitRegName) { |
+ constexpr const char Separator[] = ":"; |
+ constexpr size_t SeparatorWidth = llvm::array_lengthof(Separator) - 1; |
+ size_t Pos = RegName.find(Separator); |
+ if (Pos == std::string::npos) { |
+ *SplitRegClass = ""; |
+ *SplitRegName = RegName; |
+ } else { |
+ *SplitRegClass = RegName.substr(0, Pos); |
+ *SplitRegName = RegName.substr(Pos + SeparatorWidth); |
+ } |
+} |
+ |
} // end of anonymous namespace |
void TargetLowering::filterTypeToRegisterSet( |
GlobalContext *Ctx, int32_t NumRegs, |
llvm::SmallBitVector TypeToRegisterSet[], size_t TypeToRegisterSetSize, |
- std::function<IceString(int32_t)> getRegName) { |
- llvm::SmallBitVector ExcludeBitSet(NumRegs); |
+ std::function<IceString(int32_t)> getRegName, |
+ std::function<IceString(RegClass)> getRegClassName) { |
std::vector<llvm::SmallBitVector> UseSet(TypeToRegisterSetSize, |
- ExcludeBitSet); |
- ExcludeBitSet.flip(); |
+ llvm::SmallBitVector(NumRegs)); |
+ std::vector<llvm::SmallBitVector> ExcludeSet(TypeToRegisterSetSize, |
+ llvm::SmallBitVector(NumRegs)); |
std::unordered_map<IceString, int32_t> RegNameToIndex; |
for (int32_t RegIndex = 0; RegIndex < NumRegs; ++RegIndex) |
RegNameToIndex[getRegName(RegIndex)] = RegIndex; |
ClFlags::StringVector BadRegNames; |
- for (const IceString &RegName : Ctx->getFlags().getUseRestrictedRegisters()) { |
- if (!RegNameToIndex.count(RegName)) { |
- BadRegNames.push_back(RegName); |
- continue; |
- } |
- const int32_t RegIndex = RegNameToIndex[RegName]; |
- for (SizeT TypeIndex = 0; TypeIndex < TypeToRegisterSetSize; ++TypeIndex) |
- UseSet[TypeIndex][RegIndex] = TypeToRegisterSet[TypeIndex][RegIndex]; |
- } |
- for (const IceString &RegName : Ctx->getFlags().getExcludedRegisters()) { |
- if (!RegNameToIndex.count(RegName)) { |
- BadRegNames.push_back(RegName); |
- continue; |
+ // The processRegList function iterates across the RegNames vector. Each |
+ // entry in the vector is a string of the form "<reg>" or "<class>:<reg>". |
+ // The register class and register number are computed, and the corresponding |
+ // bit is set in RegSet[][]. If "<class>:" is missing, then the bit is set |
+ // for all classes. |
+ auto processRegList = [&](const ClFlags::StringVector &RegNames, |
+ std::vector<llvm::SmallBitVector> &RegSet) { |
+ for (const IceString &RegClassAndName : RegNames) { |
+ IceString RClass; |
+ IceString RName; |
+ splitToClassAndName(RegClassAndName, &RClass, &RName); |
+ if (!RegNameToIndex.count(RName)) { |
+ BadRegNames.push_back(RName); |
+ continue; |
+ } |
+ const int32_t RegIndex = RegNameToIndex.at(RName); |
+ for (SizeT TypeIndex = 0; TypeIndex < TypeToRegisterSetSize; |
+ ++TypeIndex) { |
+ if (RClass.empty() || |
+ RClass == getRegClassName(static_cast<RegClass>(TypeIndex))) { |
+ RegSet[TypeIndex][RegIndex] = TypeToRegisterSet[TypeIndex][RegIndex]; |
+ } |
+ } |
} |
- ExcludeBitSet[RegNameToIndex[RegName]] = false; |
- } |
+ }; |
+ |
+ processRegList(Ctx->getFlags().getUseRestrictedRegisters(), UseSet); |
+ processRegList(Ctx->getFlags().getExcludedRegisters(), ExcludeSet); |
if (!BadRegNames.empty()) { |
std::string Buffer; |
@@ -185,9 +214,10 @@ void TargetLowering::filterTypeToRegisterSet( |
for (size_t TypeIndex = 0; TypeIndex < TypeToRegisterSetSize; ++TypeIndex) { |
llvm::SmallBitVector *TypeBitSet = &TypeToRegisterSet[TypeIndex]; |
llvm::SmallBitVector *UseBitSet = &UseSet[TypeIndex]; |
+ llvm::SmallBitVector *ExcludeBitSet = &ExcludeSet[TypeIndex]; |
if (UseBitSet->any()) |
*TypeBitSet = *UseBitSet; |
- *TypeBitSet &= ExcludeBitSet; |
+ (*TypeBitSet).reset(*ExcludeBitSet); |
} |
// Display filtered register sets, if requested. |
@@ -198,13 +228,8 @@ void TargetLowering::filterTypeToRegisterSet( |
const IceString IndentTwice = Indent + Indent; |
Str << "Registers available for register allocation:\n"; |
for (size_t TypeIndex = 0; TypeIndex < TypeToRegisterSetSize; ++TypeIndex) { |
- Str << Indent; |
- if (TypeIndex < IceType_NUM) { |
- Str << typeString(static_cast<Type>(TypeIndex)); |
- } else { |
- Str << "other[" << TypeIndex << "]"; |
- } |
- Str << ":\n"; |
+ Str << Indent << getRegClassName(static_cast<RegClass>(TypeIndex)) |
+ << ":\n"; |
printRegisterSet(Str, TypeToRegisterSet[TypeIndex], getRegName, |
IndentTwice); |
} |