Index: lib/Basic/Targets/AMDGPU.h =================================================================== --- lib/Basic/Targets/AMDGPU.h +++ lib/Basic/Targets/AMDGPU.h @@ -64,6 +64,58 @@ GK_GFX9 } GPU; + struct NameGPUKind { + llvm::StringLiteral Name; + AMDGPUTargetInfo::GPUKind Kind; + }; + + static constexpr NameGPUKind R600Names[] = { + {{"r600"}, GK_R600}, + {{"rv610"}, GK_R600}, + {{"rv620"}, GK_R600}, + {{"rv630"}, GK_R600}, + {{"rv635"}, GK_R600}, + {{"rs780"}, GK_R600}, + {{"rs880"}, GK_R600}, + {{"rv670"}, GK_R600_DOUBLE_OPS}, + {{"rv710"}, GK_R700}, + {{"rv730"}, GK_R700}, + {{"rv740"}, GK_R700_DOUBLE_OPS}, + {{"rv770"}, GK_R700_DOUBLE_OPS}, + {{"palm"}, GK_EVERGREEN}, + {{"cedar"}, GK_EVERGREEN}, + {{"sumo"}, GK_EVERGREEN}, + {{"sumo2"}, GK_EVERGREEN}, + {{"redwood"}, GK_EVERGREEN}, + {{"juniper"}, GK_EVERGREEN}, + {{"hemlock"}, GK_EVERGREEN_DOUBLE_OPS}, + {{"cypress"}, GK_EVERGREEN_DOUBLE_OPS}, + {{"barts"}, GK_NORTHERN_ISLANDS}, + {{"turks"}, GK_NORTHERN_ISLANDS}, + {{"caicos"}, GK_NORTHERN_ISLANDS}, + {{"cayman"}, GK_CAYMAN}, + {{"aruba"}, GK_CAYMAN}, + }; + static constexpr NameGPUKind AMDGCNNames[] = { + {{"gfx600"}, GK_GFX6}, {{"tahiti"}, GK_GFX6}, + {{"gfx601"}, GK_GFX6}, {{"pitcairn"}, GK_GFX6}, + {{"verde"}, GK_GFX6}, {{"oland"}, GK_GFX6}, + {{"hainan"}, GK_GFX6}, {{"gfx700"}, GK_GFX7}, + {{"bonaire"}, GK_GFX7}, {{"kaveri"}, GK_GFX7}, + {{"gfx701"}, GK_GFX7}, {{"hawaii"}, GK_GFX7}, + {{"gfx702"}, GK_GFX7}, {{"gfx703"}, GK_GFX7}, + {{"kabini"}, GK_GFX7}, {{"mullins"}, GK_GFX7}, + {{"gfx800"}, GK_GFX8}, {{"iceland"}, GK_GFX8}, + {{"gfx801"}, GK_GFX8}, {{"carrizo"}, GK_GFX8}, + {{"gfx802"}, GK_GFX8}, {{"tonga"}, GK_GFX8}, + {{"gfx803"}, GK_GFX8}, {{"fiji"}, GK_GFX8}, + {{"polaris10"}, GK_GFX8}, {{"polaris11"}, GK_GFX8}, + {{"gfx804"}, GK_GFX8}, {{"gfx810"}, GK_GFX8}, + {{"stoney"}, GK_GFX8}, {{"gfx900"}, GK_GFX9}, + {{"gfx901"}, GK_GFX9}, {{"gfx902"}, GK_GFX9}, + {{"gfx903"}, GK_GFX9}, + }; + bool hasFP64 : 1; bool hasFMAF : 1; bool hasLDEXPF : 1; @@ -219,6 +271,8 @@ return GK_NONE != parseR600Name(Name); } + void fillValidCPUList(SmallVectorImpl &Values) const override; + bool setCPU(const std::string &Name) override { if (getTriple().getArch() == llvm::Triple::amdgcn) GPU = parseAMDGCNName(Name); Index: lib/Basic/Targets/AMDGPU.cpp =================================================================== --- lib/Basic/Targets/AMDGPU.cpp +++ lib/Basic/Targets/AMDGPU.cpp @@ -228,72 +228,37 @@ TargetOpts.Features.push_back("+fp64-fp16-denormals"); } + +constexpr AMDGPUTargetInfo::NameGPUKind AMDGPUTargetInfo::R600Names[]; +constexpr AMDGPUTargetInfo::NameGPUKind AMDGPUTargetInfo::AMDGCNNames[]; AMDGPUTargetInfo::GPUKind AMDGPUTargetInfo::parseR600Name(StringRef Name) { - return llvm::StringSwitch(Name) - .Case("r600", GK_R600) - .Case("rv610", GK_R600) - .Case("rv620", GK_R600) - .Case("rv630", GK_R600) - .Case("rv635", GK_R600) - .Case("rs780", GK_R600) - .Case("rs880", GK_R600) - .Case("rv670", GK_R600_DOUBLE_OPS) - .Case("rv710", GK_R700) - .Case("rv730", GK_R700) - .Case("rv740", GK_R700_DOUBLE_OPS) - .Case("rv770", GK_R700_DOUBLE_OPS) - .Case("palm", GK_EVERGREEN) - .Case("cedar", GK_EVERGREEN) - .Case("sumo", GK_EVERGREEN) - .Case("sumo2", GK_EVERGREEN) - .Case("redwood", GK_EVERGREEN) - .Case("juniper", GK_EVERGREEN) - .Case("hemlock", GK_EVERGREEN_DOUBLE_OPS) - .Case("cypress", GK_EVERGREEN_DOUBLE_OPS) - .Case("barts", GK_NORTHERN_ISLANDS) - .Case("turks", GK_NORTHERN_ISLANDS) - .Case("caicos", GK_NORTHERN_ISLANDS) - .Case("cayman", GK_CAYMAN) - .Case("aruba", GK_CAYMAN) - .Default(GK_NONE); + const auto *Result = llvm::find_if( + R600Names, [Name](const NameGPUKind &Kind) { return Kind.Name == Name; }); + + if (Result == std::end(R600Names)) + return GK_NONE; + return Result->Kind; } AMDGPUTargetInfo::GPUKind AMDGPUTargetInfo::parseAMDGCNName(StringRef Name) { - return llvm::StringSwitch(Name) - .Case("gfx600", GK_GFX6) - .Case("tahiti", GK_GFX6) - .Case("gfx601", GK_GFX6) - .Case("pitcairn", GK_GFX6) - .Case("verde", GK_GFX6) - .Case("oland", GK_GFX6) - .Case("hainan", GK_GFX6) - .Case("gfx700", GK_GFX7) - .Case("bonaire", GK_GFX7) - .Case("kaveri", GK_GFX7) - .Case("gfx701", GK_GFX7) - .Case("hawaii", GK_GFX7) - .Case("gfx702", GK_GFX7) - .Case("gfx703", GK_GFX7) - .Case("kabini", GK_GFX7) - .Case("mullins", GK_GFX7) - .Case("gfx800", GK_GFX8) - .Case("iceland", GK_GFX8) - .Case("gfx801", GK_GFX8) - .Case("carrizo", GK_GFX8) - .Case("gfx802", GK_GFX8) - .Case("tonga", GK_GFX8) - .Case("gfx803", GK_GFX8) - .Case("fiji", GK_GFX8) - .Case("polaris10", GK_GFX8) - .Case("polaris11", GK_GFX8) - .Case("gfx804", GK_GFX8) - .Case("gfx810", GK_GFX8) - .Case("stoney", GK_GFX8) - .Case("gfx900", GK_GFX9) - .Case("gfx901", GK_GFX9) - .Case("gfx902", GK_GFX9) - .Case("gfx903", GK_GFX9) - .Default(GK_NONE); + const auto *Result = + llvm::find_if(AMDGCNNames, [Name](const NameGPUKind &Kind) { + return Kind.Name == Name; + }); + + if (Result == std::end(AMDGCNNames)) + return GK_NONE; + return Result->Kind; +} + +void AMDGPUTargetInfo::fillValidCPUList( + SmallVectorImpl &Values) const { + if (getTriple().getArch() == llvm::Triple::amdgcn) + llvm::for_each(AMDGCNNames, [&Values](const NameGPUKind &Kind) { + Values.emplace_back(Kind.Name);}); + else + llvm::for_each(R600Names, [&Values](const NameGPUKind &Kind) { + Values.emplace_back(Kind.Name);}); } void AMDGPUTargetInfo::setAddressSpaceMap(bool DefaultIsPrivate) { Index: lib/Basic/Targets/AVR.h =================================================================== --- lib/Basic/Targets/AVR.h +++ lib/Basic/Targets/AVR.h @@ -167,6 +167,7 @@ } bool isValidCPUName(StringRef Name) const override; + void fillValidCPUList(SmallVectorImpl &Values) const override; bool setCPU(const std::string &Name) override { bool isValid = isValidCPUName(Name); if (isValid) Index: lib/Basic/Targets/AVR.cpp =================================================================== --- lib/Basic/Targets/AVR.cpp +++ lib/Basic/Targets/AVR.cpp @@ -28,7 +28,7 @@ }; // This list should be kept up-to-date with AVRDevices.td in LLVM. -static ArrayRef AVRMcus = { +static MCUInfo AVRMcus[] = { {"at90s1200", "__AVR_AT90S1200__"}, {"attiny11", "__AVR_ATtiny11__"}, {"attiny12", "__AVR_ATtiny12__"}, @@ -273,35 +273,29 @@ } // namespace targets } // namespace clang +static constexpr llvm::StringLiteral ValidFamilyNames[] = { + "avr1", "avr2", "avr25", "avr3", "avr31", + "avr35", "avr4", "avr5", "avr51", "avr6", + "avrxmega1", "avrxmega2", "avrxmega3", "avrxmega4", "avrxmega5", + "avrxmega6", "avrxmega7", "avrtiny"}; + bool AVRTargetInfo::isValidCPUName(StringRef Name) const { - bool IsFamily = llvm::StringSwitch(Name) - .Case("avr1", true) - .Case("avr2", true) - .Case("avr25", true) - .Case("avr3", true) - .Case("avr31", true) - .Case("avr35", true) - .Case("avr4", true) - .Case("avr5", true) - .Case("avr51", true) - .Case("avr6", true) - .Case("avrxmega1", true) - .Case("avrxmega2", true) - .Case("avrxmega3", true) - .Case("avrxmega4", true) - .Case("avrxmega5", true) - .Case("avrxmega6", true) - .Case("avrxmega7", true) - .Case("avrtiny", true) - .Default(false); + bool IsFamily = + llvm::find(ValidFamilyNames, Name) != std::end(ValidFamilyNames); bool IsMCU = - std::find_if(AVRMcus.begin(), AVRMcus.end(), [&](const MCUInfo &Info) { + llvm::find_if(AVRMcus, [&](const MCUInfo &Info) { return Info.Name == Name; - }) != AVRMcus.end(); + }) != std::end(AVRMcus); return IsFamily || IsMCU; } +void AVRTargetInfo::fillValidCPUList(SmallVectorImpl &Values) const { + Values.append(std::begin(ValidFamilyNames), std::end(ValidFamilyNames)); + for (const MCUInfo &Info : AVRMcus) + Values.push_back(Info.Name); +} + void AVRTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("AVR"); @@ -309,12 +303,10 @@ Builder.defineMacro("__AVR__"); if (!this->CPU.empty()) { - auto It = - std::find_if(AVRMcus.begin(), AVRMcus.end(), [&](const MCUInfo &Info) { - return Info.Name == this->CPU; - }); + auto It = llvm::find_if( + AVRMcus, [&](const MCUInfo &Info) { return Info.Name == this->CPU; }); - if (It != AVRMcus.end()) + if (It != std::end(AVRMcus)) Builder.defineMacro(It->DefineName); } } Index: lib/Basic/Targets/BPF.h =================================================================== --- lib/Basic/Targets/BPF.h +++ lib/Basic/Targets/BPF.h @@ -77,12 +77,9 @@ } } - bool isValidCPUName(StringRef Name) const override { - if (Name == "generic" || Name == "v1" || - Name == "v2" || Name == "probe") - return true; - return false; - } + bool isValidCPUName(StringRef Name) const override; + + void fillValidCPUList(SmallVectorImpl &Values) const override; bool setCPU(const std::string &Name) override { StringRef CPUName(Name); Index: lib/Basic/Targets/BPF.cpp =================================================================== --- lib/Basic/Targets/BPF.cpp +++ lib/Basic/Targets/BPF.cpp @@ -14,6 +14,7 @@ #include "BPF.h" #include "Targets.h" #include "clang/Basic/MacroBuilder.h" +#include "llvm/ADT/StringRef.h" using namespace clang; using namespace clang::targets; @@ -23,3 +24,14 @@ DefineStd(Builder, "bpf", Opts); Builder.defineMacro("__BPF__"); } + +static constexpr llvm::StringLiteral ValidCPUNames[] = {"generic", "v1", "v2", + "probe"}; + +bool BPFTargetInfo::isValidCPUName(StringRef Name) const { + return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); +} + +void BPFTargetInfo::fillValidCPUList(SmallVectorImpl &Values) const { + Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); +} Index: lib/Basic/Targets/Hexagon.h =================================================================== --- lib/Basic/Targets/Hexagon.h +++ lib/Basic/Targets/Hexagon.h @@ -112,6 +112,8 @@ return getHexagonCPUSuffix(Name); } + void fillValidCPUList(SmallVectorImpl &Values) const override; + bool setCPU(const std::string &Name) override { if (!isValidCPUName(Name)) return false; Index: lib/Basic/Targets/Hexagon.cpp =================================================================== --- lib/Basic/Targets/Hexagon.cpp +++ lib/Basic/Targets/Hexagon.cpp @@ -141,15 +141,29 @@ .Default(false); } +struct CPUSuffix { + llvm::StringLiteral Name; + llvm::StringLiteral Suffix; +}; + +static constexpr CPUSuffix Suffixes[] = { + {{"hexagonv4"}, {"4"}}, {{"hexagonv5"}, {"5"}}, + {{"hexagonv55"}, {"55"}}, {{"hexagonv60"}, {"60"}}, + {{"hexagonv62"}, {"62"}}, {{"hexagonv65"}, {"65"}}, +}; + const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) { - return llvm::StringSwitch(Name) - .Case("hexagonv4", "4") - .Case("hexagonv5", "5") - .Case("hexagonv55", "55") - .Case("hexagonv60", "60") - .Case("hexagonv62", "62") - .Case("hexagonv65", "65") - .Default(nullptr); + const CPUSuffix *Item = llvm::find_if( + Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; }); + if (Item == std::end(Suffixes)) + return nullptr; + return Item->Suffix.data(); +} + +void HexagonTargetInfo::fillValidCPUList( + SmallVectorImpl &Values) const { + for (const CPUSuffix &Suffix : Suffixes) + Values.push_back(Suffix.Name); } ArrayRef HexagonTargetInfo::getTargetBuiltins() const { Index: lib/Basic/Targets/Lanai.h =================================================================== --- lib/Basic/Targets/Lanai.h +++ lib/Basic/Targets/Lanai.h @@ -65,6 +65,8 @@ bool isValidCPUName(StringRef Name) const override; + void fillValidCPUList(SmallVectorImpl &Values) const override; + bool setCPU(const std::string &Name) override; bool hasFeature(StringRef Feature) const override; Index: lib/Basic/Targets/Lanai.cpp =================================================================== --- lib/Basic/Targets/Lanai.cpp +++ lib/Basic/Targets/Lanai.cpp @@ -40,6 +40,10 @@ bool LanaiTargetInfo::isValidCPUName(StringRef Name) const { return llvm::StringSwitch(Name).Case("v11", true).Default(false); } +void LanaiTargetInfo::fillValidCPUList( + SmallVectorImpl &Values) const { + Values.emplace_back("v11"); +} bool LanaiTargetInfo::setCPU(const std::string &Name) { CPU = llvm::StringSwitch(Name).Case("v11", CK_V11).Default(CK_NONE); Index: lib/Basic/Targets/Mips.h =================================================================== --- lib/Basic/Targets/Mips.h +++ lib/Basic/Targets/Mips.h @@ -161,6 +161,7 @@ } bool isValidCPUName(StringRef Name) const override; + void fillValidCPUList(SmallVectorImpl &Values) const override; bool setCPU(const std::string &Name) override { CPU = Name; Index: lib/Basic/Targets/Mips.cpp =================================================================== --- lib/Basic/Targets/Mips.cpp +++ lib/Basic/Targets/Mips.cpp @@ -44,26 +44,19 @@ return false; } +static constexpr llvm::StringLiteral ValidCPUNames[] = { + {"mips1"}, {"mips2"}, {"mips3"}, {"mips4"}, {"mips5"}, + {"mips32"}, {"mips32r2"}, {"mips32r3"}, {"mips32r5"}, {"mips32r6"}, + {"mips64"}, {"mips64r2"}, {"mips64r3"}, {"mips64r5"}, {"mips64r6"}, + {"octeon"}, {"p5600"}}; + bool MipsTargetInfo::isValidCPUName(StringRef Name) const { - return llvm::StringSwitch(Name) - .Case("mips1", true) - .Case("mips2", true) - .Case("mips3", true) - .Case("mips4", true) - .Case("mips5", true) - .Case("mips32", true) - .Case("mips32r2", true) - .Case("mips32r3", true) - .Case("mips32r5", true) - .Case("mips32r6", true) - .Case("mips64", true) - .Case("mips64r2", true) - .Case("mips64r3", true) - .Case("mips64r5", true) - .Case("mips64r6", true) - .Case("octeon", true) - .Case("p5600", true) - .Default(false); + return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); +} + +void MipsTargetInfo::fillValidCPUList( + SmallVectorImpl &Values) const { + Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); } void MipsTargetInfo::getTargetDefines(const LangOptions &Opts, Index: lib/Basic/Targets/Nios2.h =================================================================== --- lib/Basic/Targets/Nios2.h +++ lib/Basic/Targets/Nios2.h @@ -56,6 +56,10 @@ return Name == "nios2r1" || Name == "nios2r2"; } + void fillValidCPUList(SmallVectorImpl &Values) const override { + Values.append({"nios2r1", "nios2r2"}); + } + bool setCPU(const std::string &Name) override { if (isValidCPUName(Name)) { CPU = Name; Index: lib/Basic/Targets/PPC.h =================================================================== --- lib/Basic/Targets/PPC.h +++ lib/Basic/Targets/PPC.h @@ -86,6 +86,7 @@ // 821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell, // titan, rs64. bool isValidCPUName(StringRef Name) const override; + void fillValidCPUList(SmallVectorImpl &Values) const override; bool setCPU(const std::string &Name) override { bool CPUKnown = isValidCPUName(Name); Index: lib/Basic/Targets/PPC.cpp =================================================================== --- lib/Basic/Targets/PPC.cpp +++ lib/Basic/Targets/PPC.cpp @@ -479,57 +479,26 @@ return llvm::makeArrayRef(GCCRegAliases); } +static constexpr llvm::StringLiteral ValidCPUNames[] = { + {"generic"}, {"440"}, {"450"}, {"601"}, {"602"}, + {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"}, + {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"}, + {"7450"}, {"g4+"}, {"750"}, {"970"}, {"g5"}, + {"a2"}, {"a2q"}, {"e500mc"}, {"e5500"}, {"power3"}, + {"pwr3"}, {"power4"}, {"pwr4"}, {"power5"}, {"pwr5"}, + {"power5x"}, {"pwr5x"}, {"power6"}, {"pwr6"}, {"power6x"}, + {"pwr6x"}, {"power7"}, {"pwr7"}, {"power8"}, {"pwr8"}, + {"power9"}, {"pwr9"}, {"powerpc"}, {"ppc"}, {"powerpc64"}, + {"ppc64"}, {"powerpc64le"}, {"ppc64le"}, +}; + bool PPCTargetInfo::isValidCPUName(StringRef Name) const { - return llvm::StringSwitch(Name) - .Case("generic", true) - .Case("440", true) - .Case("450", true) - .Case("601", true) - .Case("602", true) - .Case("603", true) - .Case("603e", true) - .Case("603ev", true) - .Case("604", true) - .Case("604e", true) - .Case("620", true) - .Case("630", true) - .Case("g3", true) - .Case("7400", true) - .Case("g4", true) - .Case("7450", true) - .Case("g4+", true) - .Case("750", true) - .Case("970", true) - .Case("g5", true) - .Case("a2", true) - .Case("a2q", true) - .Case("e500mc", true) - .Case("e5500", true) - .Case("power3", true) - .Case("pwr3", true) - .Case("power4", true) - .Case("pwr4", true) - .Case("power5", true) - .Case("pwr5", true) - .Case("power5x", true) - .Case("pwr5x", true) - .Case("power6", true) - .Case("pwr6", true) - .Case("power6x", true) - .Case("pwr6x", true) - .Case("power7", true) - .Case("pwr7", true) - .Case("power8", true) - .Case("pwr8", true) - .Case("power9", true) - .Case("pwr9", true) - .Case("powerpc", true) - .Case("ppc", true) - .Case("powerpc64", true) - .Case("ppc64", true) - .Case("powerpc64le", true) - .Case("ppc64le", true) - .Default(false); + const StringRef *FoundName = llvm::find(ValidCPUNames, Name); + return FoundName != std::end(ValidCPUNames); +} + +void PPCTargetInfo::fillValidCPUList(SmallVectorImpl &Values) const { + Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); } void PPCTargetInfo::adjust(LangOptions &Opts) { Index: lib/Basic/Targets/Sparc.h =================================================================== --- lib/Basic/Targets/Sparc.h +++ lib/Basic/Targets/Sparc.h @@ -131,48 +131,7 @@ CG_V9, }; - CPUGeneration getCPUGeneration(CPUKind Kind) const { - switch (Kind) { - case CK_GENERIC: - case CK_V8: - case CK_SUPERSPARC: - case CK_SPARCLITE: - case CK_F934: - case CK_HYPERSPARC: - case CK_SPARCLITE86X: - case CK_SPARCLET: - case CK_TSC701: - case CK_MYRIAD2100: - case CK_MYRIAD2150: - case CK_MYRIAD2155: - case CK_MYRIAD2450: - case CK_MYRIAD2455: - case CK_MYRIAD2x5x: - case CK_MYRIAD2080: - case CK_MYRIAD2085: - case CK_MYRIAD2480: - case CK_MYRIAD2485: - case CK_MYRIAD2x8x: - case CK_LEON2: - case CK_LEON2_AT697E: - case CK_LEON2_AT697F: - case CK_LEON3: - case CK_LEON3_UT699: - case CK_LEON3_GR712RC: - case CK_LEON4: - case CK_LEON4_GR740: - return CG_V8; - case CK_V9: - case CK_ULTRASPARC: - case CK_ULTRASPARC3: - case CK_NIAGARA: - case CK_NIAGARA2: - case CK_NIAGARA3: - case CK_NIAGARA4: - return CG_V9; - } - llvm_unreachable("Unexpected CPU kind"); - } + CPUGeneration getCPUGeneration(CPUKind Kind) const; CPUKind getCPUKind(StringRef Name) const; @@ -180,6 +139,8 @@ return getCPUKind(Name) != CK_GENERIC; } + void fillValidCPUList(SmallVectorImpl &Values) const override; + bool setCPU(const std::string &Name) override { CPU = getCPUKind(Name); return CPU != CK_GENERIC; @@ -259,6 +220,8 @@ return getCPUGeneration(SparcTargetInfo::getCPUKind(Name)) == CG_V9; } + void fillValidCPUList(SmallVectorImpl &Values) const override; + bool setCPU(const std::string &Name) override { if (!SparcTargetInfo::setCPU(Name)) return false; Index: lib/Basic/Targets/Sparc.cpp =================================================================== --- lib/Basic/Targets/Sparc.cpp +++ lib/Basic/Targets/Sparc.cpp @@ -51,49 +51,81 @@ .Default(false); } +struct SparcCPUInfo { + llvm::StringLiteral Name; + SparcTargetInfo::CPUKind Kind; + SparcTargetInfo::CPUGeneration Generation; +}; + +static constexpr SparcCPUInfo CPUInfo[] = { + {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8}, + {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8}, + {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8}, + {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8}, + {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8}, + {{"sparclite86x"}, + SparcTargetInfo::CK_SPARCLITE86X, + SparcTargetInfo::CG_V8}, + {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8}, + {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8}, + {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9}, + {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9}, + {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9}, + {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9}, + {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9}, + {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9}, + {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9}, + {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8}, + {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8}, + {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8}, + {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8}, + {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8}, + {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, + {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8}, + {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8}, + {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8}, + {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8}, + {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8}, + // FIXME: the myriad2[.n] spellings are obsolete, + // but a grace period is needed to allow updating dependent builds. + {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, + {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8}, + {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, + {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8}, + {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8}, + {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8}, + {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8}, + {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8}, + {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8}, + {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8}, + {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8}, + {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8}, +}; + +SparcTargetInfo::CPUGeneration +SparcTargetInfo::getCPUGeneration(CPUKind Kind) const { + if (Kind == CK_GENERIC) + return CG_V8; + const SparcCPUInfo *Item = llvm::find_if( + CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; }); + if (Item == std::end(CPUInfo)) + llvm_unreachable("Unexpected CPU kind"); + return Item->Generation; +} + SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const { - return llvm::StringSwitch(Name) - .Case("v8", CK_V8) - .Case("supersparc", CK_SUPERSPARC) - .Case("sparclite", CK_SPARCLITE) - .Case("f934", CK_F934) - .Case("hypersparc", CK_HYPERSPARC) - .Case("sparclite86x", CK_SPARCLITE86X) - .Case("sparclet", CK_SPARCLET) - .Case("tsc701", CK_TSC701) - .Case("v9", CK_V9) - .Case("ultrasparc", CK_ULTRASPARC) - .Case("ultrasparc3", CK_ULTRASPARC3) - .Case("niagara", CK_NIAGARA) - .Case("niagara2", CK_NIAGARA2) - .Case("niagara3", CK_NIAGARA3) - .Case("niagara4", CK_NIAGARA4) - .Case("ma2100", CK_MYRIAD2100) - .Case("ma2150", CK_MYRIAD2150) - .Case("ma2155", CK_MYRIAD2155) - .Case("ma2450", CK_MYRIAD2450) - .Case("ma2455", CK_MYRIAD2455) - .Case("ma2x5x", CK_MYRIAD2x5x) - .Case("ma2080", CK_MYRIAD2080) - .Case("ma2085", CK_MYRIAD2085) - .Case("ma2480", CK_MYRIAD2480) - .Case("ma2485", CK_MYRIAD2485) - .Case("ma2x8x", CK_MYRIAD2x8x) - // FIXME: the myriad2[.n] spellings are obsolete, - // but a grace period is needed to allow updating dependent builds. - .Case("myriad2", CK_MYRIAD2x5x) - .Case("myriad2.1", CK_MYRIAD2100) - .Case("myriad2.2", CK_MYRIAD2x5x) - .Case("myriad2.3", CK_MYRIAD2x8x) - .Case("leon2", CK_LEON2) - .Case("at697e", CK_LEON2_AT697E) - .Case("at697f", CK_LEON2_AT697F) - .Case("leon3", CK_LEON3) - .Case("ut699", CK_LEON3_UT699) - .Case("gr712rc", CK_LEON3_GR712RC) - .Case("leon4", CK_LEON4) - .Case("gr740", CK_LEON4_GR740) - .Default(CK_GENERIC); + const SparcCPUInfo *Item = llvm::find_if( + CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; }); + + if (Item == std::end(CPUInfo)) + return CK_GENERIC; + return Item->Kind; +} + +void SparcTargetInfo::fillValidCPUList( + SmallVectorImpl &Values) const { + for (const SparcCPUInfo &Info : CPUInfo) + Values.push_back(Info.Name); } void SparcTargetInfo::getTargetDefines(const LangOptions &Opts, @@ -202,3 +234,10 @@ Builder.defineMacro("__sparcv9__"); } } + +void SparcV9TargetInfo::fillValidCPUList( + SmallVectorImpl &Values) const { + for (const SparcCPUInfo &Info : CPUInfo) + if (Info.Generation == CG_V9) + Values.push_back(Info.Name); +} Index: lib/Basic/Targets/SystemZ.h =================================================================== --- lib/Basic/Targets/SystemZ.h +++ lib/Basic/Targets/SystemZ.h @@ -82,6 +82,8 @@ return getISARevision(Name) != -1; } + void fillValidCPUList(SmallVectorImpl &Values) const override; + bool setCPU(const std::string &Name) override { CPU = Name; ISARevision = getISARevision(CPU); Index: lib/Basic/Targets/SystemZ.cpp =================================================================== --- lib/Basic/Targets/SystemZ.cpp +++ lib/Basic/Targets/SystemZ.cpp @@ -83,14 +83,32 @@ } } +struct ISANameRevision { + llvm::StringLiteral Name; + int ISARevisionID; +}; +static constexpr ISANameRevision ISARevisions[] = { + {{"arch8"}, 8}, {{"z10"}, 8}, + {{"arch9"}, 9}, {{"z196"}, 9}, + {{"arch10"}, 10}, {{"zEC12"}, 10}, + {{"arch11"}, 11}, {{"z13"}, 11}, + {{"arch12"}, 12}, {{"z14"}, 12} +}; + int SystemZTargetInfo::getISARevision(StringRef Name) const { - return llvm::StringSwitch(Name) - .Cases("arch8", "z10", 8) - .Cases("arch9", "z196", 9) - .Cases("arch10", "zEC12", 10) - .Cases("arch11", "z13", 11) - .Cases("arch12", "z14", 12) - .Default(-1); + const auto Rev = + llvm::find_if(ISARevisions, [Name](const ISANameRevision &CR) { + return CR.Name == Name; + }); + if (Rev == std::end(ISARevisions)) + return -1; + return Rev->ISARevisionID; +} + +void SystemZTargetInfo::fillValidCPUList( + SmallVectorImpl &Values) const { + for (const ISANameRevision &Rev : ISARevisions) + Values.push_back(Rev.Name); } bool SystemZTargetInfo::hasFeature(StringRef Feature) const { Index: lib/Basic/Targets/WebAssembly.h =================================================================== --- lib/Basic/Targets/WebAssembly.h +++ lib/Basic/Targets/WebAssembly.h @@ -74,6 +74,7 @@ DiagnosticsEngine &Diags) final; bool isValidCPUName(StringRef Name) const final; + void fillValidCPUList(SmallVectorImpl &Values) const final; bool setCPU(const std::string &Name) final { return isValidCPUName(Name); } Index: lib/Basic/Targets/WebAssembly.cpp =================================================================== --- lib/Basic/Targets/WebAssembly.cpp +++ lib/Basic/Targets/WebAssembly.cpp @@ -29,6 +29,9 @@ #include "clang/Basic/BuiltinsWebAssembly.def" }; +static constexpr llvm::StringLiteral ValidCPUNames[] = { + {"mvp"}, {"bleeding-edge"}, {"generic"}}; + bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch(Feature) .Case("simd128", SIMDLevel >= SIMD128) @@ -38,11 +41,12 @@ } bool WebAssemblyTargetInfo::isValidCPUName(StringRef Name) const { - return llvm::StringSwitch(Name) - .Case("mvp", true) - .Case("bleeding-edge", true) - .Case("generic", true) - .Default(false); + return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); +} + +void WebAssemblyTargetInfo::fillValidCPUList( + SmallVectorImpl &Values) const { + Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); } void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts,