Chromium Code Reviews| Index: src/IceTargetLowering.cpp |
| diff --git a/src/IceTargetLowering.cpp b/src/IceTargetLowering.cpp |
| index bd5c11b47e4fd0548a6084bf3a0c75a4516f0f42..fe559b50ed11f0d1ca459e253122df8e73d47803 100644 |
| --- a/src/IceTargetLowering.cpp |
| +++ b/src/IceTargetLowering.cpp |
| @@ -138,39 +138,69 @@ 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)), |
| + 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; |
| - } |
| - ExcludeBitSet[RegNameToIndex[RegName]] = false; |
| - } |
| + // 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 = |
| + [&BadRegNames, RegNameToIndex, TypeToRegisterSet, TypeToRegisterSetSize, |
|
Karl
2016/01/22 17:10:54
Why not just use [&] and let the compiler figure o
Jim Stichnoth
2016/01/22 19:02:17
Sweet, I had no idea!
|
| + getRegClassName](const ClFlags::StringVector &RegNames, |
| + std::vector<llvm::SmallBitVector> &RegSet) { |
| + for (const IceString &RegClassAndName : RegNames) { |
| + IceString RClass, RName; |
|
Karl
2016/01/22 17:10:54
I don't think our style allowed multiple variables
Jim Stichnoth
2016/01/22 19:02:17
Not sure that style issue is actually addressed an
|
| + 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]; |
| + } |
| + } |
| + } |
| + }; |
| + |
| + processRegList(Ctx->getFlags().getUseRestrictedRegisters(), UseSet); |
| + processRegList(Ctx->getFlags().getExcludedRegisters(), ExcludeSet); |
| if (!BadRegNames.empty()) { |
| std::string Buffer; |
| @@ -185,9 +215,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 +229,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); |
| } |