Skip to content

Commit

Permalink
[X86] Move CPUKind enum from clang to llvm/lib/Support. NFCI
Browse files Browse the repository at this point in the history
Similar to what some other targets have done. This information
could be reused by other frontends so doesn't make sense to live
in clang.

-Rename CK_Generic to CK_None to better reflect its illegalness.
-Move function for translating from string to enum into llvm.
-Call checkCPUKind directly from the string to enum translation
and update CPU kind to CK_None accordinly. Caller will use CK_None
as sentinel for bad CPU.

I'm planning to move all the CPU to feature mapping out next. As
part of that I want to devise a better way to express CPUs inheriting
features from an earlier CPU. Allowing this to be expressed in a
less rigid way than just falling through a switch. Or using gotos
as we've had to do lately.

Differential Revision: https://reviews.llvm.org/D81439
  • Loading branch information
topperc committed Jun 9, 2020
1 parent 44b355f commit d5c28c4
Show file tree
Hide file tree
Showing 7 changed files with 364 additions and 295 deletions.
240 changes: 0 additions & 240 deletions clang/include/clang/Basic/X86Target.def
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,6 @@
//
//===----------------------------------------------------------------------===//

#ifndef PROC_WITH_FEAT
#define PROC_WITH_FEAT(ENUM, STRING, IS64BIT, KEYFEATURE) \
PROC(ENUM, STRING, IS64BIT)
#endif

#ifndef PROC
#define PROC(ENUM, STRING, IS64BIT)
#endif

#ifndef PROC_ALIAS
#define PROC_ALIAS(ENUM, ALIAS)
#endif

#ifndef FEATURE
#define FEATURE(ENUM)
#endif
Expand All @@ -36,230 +23,6 @@
#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME)
#endif

#define PROC_64_BIT true
#define PROC_32_BIT false

/// \name i386
/// i386-generation processors.
//@{
PROC(i386, "i386", PROC_32_BIT)
//@}

/// \name i486
/// i486-generation processors.
//@{
PROC(i486, "i486", PROC_32_BIT)
PROC(WinChipC6, "winchip-c6", PROC_32_BIT)
PROC(WinChip2, "winchip2", PROC_32_BIT)
PROC(C3, "c3", PROC_32_BIT)
//@}

/// \name i586
/// i586-generation processors, P5 microarchitecture based.
//@{
PROC(i586, "i586", PROC_32_BIT)
PROC(Pentium, "pentium", PROC_32_BIT)
PROC(PentiumMMX, "pentium-mmx", PROC_32_BIT)
//@}

/// \name i686
/// i686-generation processors, P6 / Pentium M microarchitecture based.
//@{
PROC(PentiumPro, "pentiumpro", PROC_32_BIT)
PROC(i686, "i686", PROC_32_BIT)
PROC(Pentium2, "pentium2", PROC_32_BIT)
PROC(Pentium3, "pentium3", PROC_32_BIT)
PROC_ALIAS(Pentium3, "pentium3m")
PROC(PentiumM, "pentium-m", PROC_32_BIT)
PROC(C3_2, "c3-2", PROC_32_BIT)

/// This enumerator is a bit odd, as GCC no longer accepts -march=yonah.
/// Clang however has some logic to support this.
// FIXME: Warn, deprecate, and potentially remove this.
PROC(Yonah, "yonah", PROC_32_BIT)
//@}

/// \name Netburst
/// Netburst microarchitecture based processors.
//@{
PROC(Pentium4, "pentium4", PROC_32_BIT)
PROC_ALIAS(Pentium4, "pentium4m")

PROC(Prescott, "prescott", PROC_32_BIT)
PROC(Nocona, "nocona", PROC_64_BIT)
//@}

/// \name Core
/// Core microarchitecture based processors.
//@{
PROC_WITH_FEAT(Core2, "core2", PROC_64_BIT, FEATURE_SSSE3)

/// This enumerator, like Yonah, is a bit odd. It is another
/// codename which GCC no longer accepts as an option to -march, but Clang
/// has some logic for recognizing it.
// FIXME: Warn, deprecate, and potentially remove this.
PROC(Penryn, "penryn", PROC_64_BIT)
//@}

/// \name Atom
/// Atom processors
//@{
PROC_WITH_FEAT(Bonnell, "bonnell", PROC_64_BIT, FEATURE_SSSE3)
PROC_ALIAS(Bonnell, "atom")

PROC_WITH_FEAT(Silvermont, "silvermont", PROC_64_BIT, FEATURE_SSE4_2)
PROC_ALIAS(Silvermont, "slm")

PROC(Goldmont, "goldmont", PROC_64_BIT)
PROC(GoldmontPlus, "goldmont-plus", PROC_64_BIT)

PROC(Tremont, "tremont", PROC_64_BIT)
//@}

/// \name Nehalem
/// Nehalem microarchitecture based processors.
PROC_WITH_FEAT(Nehalem, "nehalem", PROC_64_BIT, FEATURE_SSE4_2)
PROC_ALIAS(Nehalem, "corei7")

/// \name Westmere
/// Westmere microarchitecture based processors.
PROC_WITH_FEAT(Westmere, "westmere", PROC_64_BIT, FEATURE_PCLMUL)

/// \name Sandy Bridge
/// Sandy Bridge microarchitecture based processors.
PROC_WITH_FEAT(SandyBridge, "sandybridge", PROC_64_BIT, FEATURE_AVX)
PROC_ALIAS(SandyBridge, "corei7-avx")

/// \name Ivy Bridge
/// Ivy Bridge microarchitecture based processors.
PROC_WITH_FEAT(IvyBridge, "ivybridge", PROC_64_BIT, FEATURE_AVX)
PROC_ALIAS(IvyBridge, "core-avx-i")

/// \name Haswell
/// Haswell microarchitecture based processors.
PROC_WITH_FEAT(Haswell, "haswell", PROC_64_BIT, FEATURE_AVX2)
PROC_ALIAS(Haswell, "core-avx2")

/// \name Broadwell
/// Broadwell microarchitecture based processors.
PROC_WITH_FEAT(Broadwell, "broadwell", PROC_64_BIT, FEATURE_AVX2)

/// \name Skylake Client
/// Skylake client microarchitecture based processors.
PROC_WITH_FEAT(SkylakeClient, "skylake", PROC_64_BIT, FEATURE_AVX2)

/// \name Skylake Server
/// Skylake server microarchitecture based processors.
PROC_WITH_FEAT(SkylakeServer, "skylake-avx512", PROC_64_BIT, FEATURE_AVX512F)
PROC_ALIAS(SkylakeServer, "skx")

/// \name Cascadelake Server
/// Cascadelake Server microarchitecture based processors.
PROC_WITH_FEAT(Cascadelake, "cascadelake", PROC_64_BIT, FEATURE_AVX512VNNI)

/// \name Cooperlake Server
/// Cooperlake Server microarchitecture based processors.
PROC_WITH_FEAT(Cooperlake, "cooperlake", PROC_64_BIT, FEATURE_AVX512BF16)

/// \name Cannonlake Client
/// Cannonlake client microarchitecture based processors.
PROC_WITH_FEAT(Cannonlake, "cannonlake", PROC_64_BIT, FEATURE_AVX512VBMI)

/// \name Icelake Client
/// Icelake client microarchitecture based processors.
PROC(IcelakeClient, "icelake-client", PROC_64_BIT)

/// \name Icelake Server
/// Icelake server microarchitecture based processors.
PROC(IcelakeServer, "icelake-server", PROC_64_BIT)

/// \name Tigerlake
/// Tigerlake microarchitecture based processors.
PROC(Tigerlake, "tigerlake", PROC_64_BIT)

/// \name Knights Landing
/// Knights Landing processor.
PROC_WITH_FEAT(KNL, "knl", PROC_64_BIT, FEATURE_AVX512F)

/// \name Knights Mill
/// Knights Mill processor.
PROC_WITH_FEAT(KNM, "knm", PROC_64_BIT, FEATURE_AVX5124FMAPS)

/// \name Lakemont
/// Lakemont microarchitecture based processors.
PROC(Lakemont, "lakemont", PROC_32_BIT)

/// \name K6
/// K6 architecture processors.
//@{
PROC(K6, "k6", PROC_32_BIT)
PROC(K6_2, "k6-2", PROC_32_BIT)
PROC(K6_3, "k6-3", PROC_32_BIT)
//@}

/// \name K7
/// K7 architecture processors.
//@{
PROC(Athlon, "athlon", PROC_32_BIT)
PROC_ALIAS(Athlon, "athlon-tbird")

PROC(AthlonXP, "athlon-xp", PROC_32_BIT)
PROC_ALIAS(AthlonXP, "athlon-mp")
PROC_ALIAS(AthlonXP, "athlon-4")
//@}

/// \name K8
/// K8 architecture processors.
//@{
PROC(K8, "k8", PROC_64_BIT)
PROC_ALIAS(K8, "athlon64")
PROC_ALIAS(K8, "athlon-fx")
PROC_ALIAS(K8, "opteron")

PROC(K8SSE3, "k8-sse3", PROC_64_BIT)
PROC_ALIAS(K8SSE3, "athlon64-sse3")
PROC_ALIAS(K8SSE3, "opteron-sse3")

PROC_WITH_FEAT(AMDFAM10, "amdfam10", PROC_64_BIT, FEATURE_SSE4_A)
PROC_ALIAS(AMDFAM10, "barcelona")
//@}

/// \name Bobcat
/// Bobcat architecture processors.
//@{
PROC_WITH_FEAT(BTVER1, "btver1", PROC_64_BIT, FEATURE_SSE4_A)
PROC_WITH_FEAT(BTVER2, "btver2", PROC_64_BIT, FEATURE_BMI)
//@}

/// \name Bulldozer
/// Bulldozer architecture processors.
//@{
PROC_WITH_FEAT(BDVER1, "bdver1", PROC_64_BIT, FEATURE_XOP)
PROC_WITH_FEAT(BDVER2, "bdver2", PROC_64_BIT, FEATURE_FMA)
PROC_WITH_FEAT(BDVER3, "bdver3", PROC_64_BIT, FEATURE_FMA)
PROC_WITH_FEAT(BDVER4, "bdver4", PROC_64_BIT, FEATURE_AVX2)
//@}

/// \name zen
/// Zen architecture processors.
//@{
PROC_WITH_FEAT(ZNVER1, "znver1", PROC_64_BIT, FEATURE_AVX2)
PROC_WITH_FEAT(ZNVER2, "znver2", PROC_64_BIT, FEATURE_AVX2)
//@}

/// This specification is deprecated and will be removed in the future.
/// Users should prefer K8.
// FIXME: Warn on this when the CPU is set to it.
//@{
PROC(x86_64, "x86-64", PROC_64_BIT)
//@}

/// \name Geode
/// Geode processors.
//@{
PROC(Geode, "geode", PROC_32_BIT)
//@}

// List of CPU Supports features in order. These need to remain in the order
// required by attribute 'target' checking. Note that not all are supported/
// prioritized by GCC, so synchronization with GCC's implementation may require
Expand Down Expand Up @@ -345,6 +108,3 @@ CPU_SPECIFIC("knm", 'j', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+mo
#undef PROC_64_BIT
#undef PROC_32_BIT
#undef FEATURE
#undef PROC
#undef PROC_ALIAS
#undef PROC_WITH_FEAT
55 changes: 15 additions & 40 deletions clang/lib/Basic/Targets/X86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,19 +109,20 @@ bool X86TargetInfo::initFeatureMap(
if (getTriple().getArch() == llvm::Triple::x86_64)
setFeatureEnabledImpl(Features, "sse2", true);

const CPUKind Kind = getCPUKind(CPU);
using namespace llvm::X86;
const enum CPUKind Kind = parseArchX86(CPU);

// Enable X87 for all X86 processors but Lakemont.
if (Kind != CK_Lakemont)
setFeatureEnabledImpl(Features, "x87", true);

// Enable cmpxchg8 for i586 and greater CPUs. Include generic for backwards
// compatibility.
if (Kind >= CK_i586 || Kind == CK_Generic)
if (Kind >= CK_i586 || Kind == CK_None)
setFeatureEnabledImpl(Features, "cx8", true);

switch (Kind) {
case CK_Generic:
case CK_None:
case CK_i386:
case CK_i486:
case CK_i586:
Expand Down Expand Up @@ -936,8 +937,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
// Subtarget options.
// FIXME: We are hard-coding the tune parameters based on the CPU, but they
// truly should be based on -mtune options.
using namespace llvm::X86;
switch (CPU) {
case CK_Generic:
case CK_None:
break;
case CK_i386:
// The rest are coming from the i386 define above.
Expand Down Expand Up @@ -1324,7 +1326,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
break;
}

if (CPU >= CK_i486 || CPU == CK_Generic) {
if (CPU >= CK_i486 || CPU == CK_None) {
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
Expand Down Expand Up @@ -1548,16 +1550,17 @@ static unsigned getFeaturePriority(llvm::X86::ProcessorFeatures Feat) {
unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const {
// Valid CPUs have a 'key feature' that compares just better than its key
// feature.
CPUKind Kind = getCPUKind(Name);
if (Kind != CK_Generic) {
using namespace llvm::X86;
CPUKind Kind = parseArchX86(Name);
if (Kind != CK_None) {
switch (Kind) {
default:
llvm_unreachable(
"CPU Type without a key feature used in 'target' attribute");
#define PROC_WITH_FEAT(ENUM, STR, IS64, KEY_FEAT) \
case CK_##ENUM: \
return (getFeaturePriority(llvm::X86::KEY_FEAT) << 1) + 1;
#include "clang/Basic/X86Target.def"
#include "llvm/Support/X86TargetParser.def"
}
}

Expand Down Expand Up @@ -1761,6 +1764,7 @@ bool X86TargetInfo::validateAsmConstraint(
// | Knights Mill | 64 | https://software.intel.com/sites/default/files/managed/9e/bc/64-ia-32-architectures-optimization-manual.pdf?countrylabel=Colombia "2.5.5.2 L1 DCache " |
// +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {
using namespace llvm::X86;
switch (CPU) {
// i386
case CK_i386:
Expand Down Expand Up @@ -1846,7 +1850,7 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {

// The following currently have unknown cache line sizes (but they are probably all 64):
// Core
case CK_Generic:
case CK_None:
return None;
}
llvm_unreachable("Unknown CPU kind");
Expand Down Expand Up @@ -1977,38 +1981,9 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {
}
}

bool X86TargetInfo::checkCPUKind(CPUKind Kind) const {
// Perform any per-CPU checks necessary to determine if this CPU is
// acceptable.
switch (Kind) {
case CK_Generic:
// No processor selected!
return false;
#define PROC(ENUM, STRING, IS64BIT) \
case CK_##ENUM: \
return IS64BIT || getTriple().getArch() == llvm::Triple::x86;
#include "clang/Basic/X86Target.def"
}
llvm_unreachable("Unhandled CPU kind");
}

void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
#define PROC(ENUM, STRING, IS64BIT) \
if (IS64BIT || getTriple().getArch() == llvm::Triple::x86) \
Values.emplace_back(STRING);
// For aliases we need to lookup the CPUKind to check get the 64-bit ness.
#define PROC_ALIAS(ENUM, ALIAS) \
if (checkCPUKind(CK_##ENUM)) \
Values.emplace_back(ALIAS);
#include "clang/Basic/X86Target.def"
}

X86TargetInfo::CPUKind X86TargetInfo::getCPUKind(StringRef CPU) const {
return llvm::StringSwitch<CPUKind>(CPU)
#define PROC(ENUM, STRING, IS64BIT) .Case(STRING, CK_##ENUM)
#define PROC_ALIAS(ENUM, ALIAS) .Case(ALIAS, CK_##ENUM)
#include "clang/Basic/X86Target.def"
.Default(CK_Generic);
bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
llvm::X86::fillValidCPUArchList(Values, Only64Bit);
}

ArrayRef<const char *> X86TargetInfo::getGCCRegNames() const {
Expand Down
Loading

0 comments on commit d5c28c4

Please sign in to comment.