Index: src/IceTargetLowering.cpp |
diff --git a/src/IceTargetLowering.cpp b/src/IceTargetLowering.cpp |
index 04f77e61b2caf26ea4fe4bedffc1efae35434fcd..4f192266287b9fc713d366dd429b2be8b3523530 100644 |
--- a/src/IceTargetLowering.cpp |
+++ b/src/IceTargetLowering.cpp |
@@ -39,7 +39,7 @@ |
// createTargetDataLowering(Ice::GlobalContext*); |
// unique_ptr<Ice::TargetHeaderLowering> |
// createTargetHeaderLowering(Ice::GlobalContext *); |
-// void staticInit(const ::Ice::ClFlags &Flags); |
+// void staticInit(::Ice::GlobalContext *); |
// } |
#define SUBZERO_TARGET(X) \ |
namespace X { \ |
@@ -49,7 +49,7 @@ |
createTargetDataLowering(::Ice::GlobalContext *Ctx); \ |
std::unique_ptr<::Ice::TargetHeaderLowering> \ |
createTargetHeaderLowering(::Ice::GlobalContext *Ctx); \ |
- void staticInit(const ::Ice::ClFlags &Flags); \ |
+ void staticInit(::Ice::GlobalContext *Ctx); \ |
} // end of namespace X |
#include "llvm/Config/SZTargets.def" |
#undef SUBZERO_TARGET |
@@ -116,6 +116,102 @@ Variable *LoweringContext::availabilityGet(Operand *Src) const { |
return nullptr; |
} |
+namespace { |
+ |
+void printRegisterSet(Ostream &Str, const llvm::SmallBitVector &Bitset, |
+ std::function<IceString(int32_t)> getRegName, |
+ const IceString &LineIndentString) { |
+ constexpr size_t RegistersPerLine = 16; |
+ size_t Count = 0; |
+ for (int i = Bitset.find_first(); i != -1; i = Bitset.find_next(i)) { |
+ if (Count == 0) { |
+ Str << LineIndentString; |
+ } else { |
+ Str << ","; |
+ } |
+ if (Count > 0 && Count % RegistersPerLine == 0) |
+ Str << "\n" << LineIndentString; |
+ ++Count; |
+ Str << getRegName(i); |
+ } |
+ if (Count) |
+ Str << "\n"; |
+} |
+ |
+} // 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::vector<llvm::SmallBitVector> UseSet(TypeToRegisterSetSize, |
+ ExcludeBitSet); |
+ ExcludeBitSet.flip(); |
+ |
+ 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; |
+ } |
+ |
+ if (!BadRegNames.empty()) { |
+ std::string Buffer; |
+ llvm::raw_string_ostream StrBuf(Buffer); |
+ StrBuf << "Unrecognized use/exclude registers:"; |
+ for (const auto &RegName : BadRegNames) |
+ StrBuf << " " << RegName; |
+ llvm::report_fatal_error(StrBuf.str()); |
+ } |
+ |
+ // Apply filters. |
+ for (size_t TypeIndex = 0; TypeIndex < TypeToRegisterSetSize; ++TypeIndex) { |
+ llvm::SmallBitVector *TypeBitSet = &TypeToRegisterSet[TypeIndex]; |
+ llvm::SmallBitVector *UseBitSet = &UseSet[TypeIndex]; |
+ if (UseBitSet->any()) |
+ *TypeBitSet = *UseBitSet; |
+ *TypeBitSet &= ExcludeBitSet; |
+ } |
+ |
+ // Display filtered register sets, if requested. |
+ if (BuildDefs::dump() && NumRegs && |
+ (Ctx->getFlags().getVerbose() & IceV_AvailableRegs)) { |
+ Ostream &Str = Ctx->getStrDump(); |
+ const IceString Indent = " "; |
+ 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"; |
+ printRegisterSet(Str, TypeToRegisterSet[TypeIndex], getRegName, |
+ IndentTwice); |
+ } |
+ Str << "\n"; |
+ } |
+} |
+ |
std::unique_ptr<TargetLowering> |
TargetLowering::createLowering(TargetArch Target, Cfg *Func) { |
switch (Target) { |
@@ -129,8 +225,8 @@ TargetLowering::createLowering(TargetArch Target, Cfg *Func) { |
} |
} |
-void TargetLowering::staticInit(const ClFlags &Flags) { |
- const TargetArch Target = Flags.getTargetArch(); |
+void TargetLowering::staticInit(GlobalContext *Ctx) { |
+ const TargetArch Target = Ctx->getFlags().getTargetArch(); |
// Call the specified target's static initializer. |
switch (Target) { |
default: |
@@ -142,7 +238,7 @@ void TargetLowering::staticInit(const ClFlags &Flags) { |
return; \ |
} \ |
InitGuard##X = true; \ |
- ::X::staticInit(Flags); \ |
+ ::X::staticInit(Ctx); \ |
} break; |
#include "llvm/Config/SZTargets.def" |
#undef SUBZERO_TARGET |