https://github.com/diggerlin created https://github.com/llvm/llvm-project/pull/137670
1. The PR proceeds with a backend target hook to allow front-ends to determine what features are available in a compilation based on the CPU name. 2. Fix a backend target feature bug that supports HTM for Power8/9/10/11. However, HTM is only supported on Power8/9 according to the ISA. 3. All target features that are hardcoded in PPC.cpp can be retrieved from the backend target feature. I have double-checked that the hardcoded logic for inferring target features from the CPU in the frontend(PPC.cpp) is the same as in PPC.td. >From 97f10e6a0fb4c158359e79e24650f8fdf4d23ef2 Mon Sep 17 00:00:00 2001 From: zhijian <zhij...@ca.ibm.com> Date: Fri, 25 Apr 2025 13:09:47 +0000 Subject: [PATCH] implement getting target features from backend for clang frontend --- clang/lib/Basic/Targets/PPC.cpp | 150 +----------------- .../cxx11-thread-local-reference.cpp | 2 +- .../Driver/aix-shared-lib-tls-model-opt.c | 7 +- .../Driver/aix-small-local-exec-dynamic-tls.c | 15 +- clang/test/Driver/ppc-crbits.cpp | 4 - clang/test/Driver/ppc-isa-features.cpp | 22 +-- llvm/include/llvm/MC/MCSubtargetInfo.h | 32 +++- .../llvm/TargetParser/PPCTargetParser.h | 5 + llvm/lib/MC/MCSubtargetInfo.cpp | 32 +++- llvm/lib/Target/PowerPC/PPC.td | 4 +- llvm/lib/TargetParser/CMakeLists.txt | 8 + llvm/lib/TargetParser/PPCTargetParser.cpp | 26 +++ llvm/utils/TableGen/SubtargetEmitter.cpp | 52 ++++-- 13 files changed, 159 insertions(+), 200 deletions(-) diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 425ad68bb9098..2a1024be1d537 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -15,6 +15,7 @@ #include "clang/Basic/MacroBuilder.h" #include "clang/Basic/TargetBuiltins.h" #include "llvm/TargetParser/PPCTargetParser.h" +#include <optional> using namespace clang; using namespace clang::targets; @@ -516,130 +517,15 @@ static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, bool PPCTargetInfo::initFeatureMap( llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeaturesVec) const { - Features["altivec"] = llvm::StringSwitch<bool>(CPU) - .Case("7400", true) - .Case("g4", true) - .Case("7450", true) - .Case("g4+", true) - .Case("970", true) - .Case("g5", true) - .Case("pwr6", true) - .Case("pwr7", true) - .Case("pwr8", true) - .Case("pwr9", true) - .Case("ppc64", true) - .Case("ppc64le", true) - .Default(false); - - Features["power9-vector"] = (CPU == "pwr9"); - Features["crypto"] = llvm::StringSwitch<bool>(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - Features["power8-vector"] = llvm::StringSwitch<bool>(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - Features["bpermd"] = llvm::StringSwitch<bool>(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Case("pwr7", true) - .Default(false); - Features["extdiv"] = llvm::StringSwitch<bool>(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Case("pwr7", true) - .Default(false); - Features["direct-move"] = llvm::StringSwitch<bool>(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - Features["crbits"] = llvm::StringSwitch<bool>(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - Features["vsx"] = llvm::StringSwitch<bool>(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Case("pwr7", true) - .Default(false); - Features["htm"] = llvm::StringSwitch<bool>(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - - // ROP Protect is off by default. - Features["rop-protect"] = false; - // Privileged instructions are off by default. - Features["privileged"] = false; - if (getTriple().isOSAIX()) { - // The code generated by the -maix-small-local-[exec|dynamic]-tls option is - // turned off by default. - Features["aix-small-local-exec-tls"] = false; - Features["aix-small-local-dynamic-tls"] = false; - - // Turn off TLS model opt by default. - Features["aix-shared-lib-tls-model-opt"] = false; - } - - Features["spe"] = llvm::StringSwitch<bool>(CPU) - .Case("8548", true) - .Case("e500", true) - .Default(false); - - Features["isa-v206-instructions"] = llvm::StringSwitch<bool>(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Case("pwr7", true) - .Case("a2", true) - .Default(false); - - Features["isa-v207-instructions"] = llvm::StringSwitch<bool>(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - - Features["isa-v30-instructions"] = - llvm::StringSwitch<bool>(CPU).Case("pwr9", true).Default(false); - - Features["quadword-atomics"] = - getTriple().isArch64Bit() && llvm::StringSwitch<bool>(CPU) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - - // Power10 includes all the same features as Power9 plus any features specific - // to the Power10 core. - if (CPU == "pwr10" || CPU == "power10") { - initFeatureMap(Features, Diags, "pwr9", FeaturesVec); - addP10SpecificFeatures(Features); - } - - // Power11 includes all the same features as Power10 plus any features - // specific to the Power11 core. - if (CPU == "pwr11" || CPU == "power11") { - initFeatureMap(Features, Diags, "pwr10", FeaturesVec); - addP11SpecificFeatures(Features); - } - - // Future CPU should include all of the features of Power 11 as well as any - // additional features (yet to be determined) specific to it. - if (CPU == "future") { - initFeatureMap(Features, Diags, "pwr11", FeaturesVec); - addFutureSpecificFeatures(Features); - } + const llvm::Triple &TheTriple = getTriple(); + std::optional<llvm::StringMap<bool>> FeaturesOpt = + llvm::PPC::getPPCDefaultTargetFeatures(TheTriple, + llvm::PPC::normalizeCPUName(CPU)); + if (FeaturesOpt.has_value()) + Features = FeaturesOpt.value(); + if (!ppcUserFeaturesCheck(Diags, FeaturesVec)) return false; @@ -694,26 +580,6 @@ bool PPCTargetInfo::initFeatureMap( return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } -// Add any Power10 specific features. -void PPCTargetInfo::addP10SpecificFeatures( - llvm::StringMap<bool> &Features) const { - Features["htm"] = false; // HTM was removed for P10. - Features["paired-vector-memops"] = true; - Features["mma"] = true; - Features["power10-vector"] = true; - Features["pcrelative-memops"] = true; - Features["prefix-instrs"] = true; - Features["isa-v31-instructions"] = true; -} - -// Add any Power11 specific features. -void PPCTargetInfo::addP11SpecificFeatures( - llvm::StringMap<bool> &Features) const {} - -// Add features specific to the "Future" CPU. -void PPCTargetInfo::addFutureSpecificFeatures( - llvm::StringMap<bool> &Features) const {} - bool PPCTargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch<bool>(Feature) .Case("powerpc", true) diff --git a/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp index cd5a18f39060e..a0e76e8a9a0b6 100644 --- a/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp +++ b/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp @@ -35,5 +35,5 @@ int &g() { return r; } // DARWIN-LABEL: define internal cxx_fast_tlscc void @__tls_init() // CHECK: call void @[[R_INIT]]() -// LINUX_AIX: attributes [[ATTR0]] = { {{.*}}"target-features"{{.*}} } +// LINUX_AIX: attributes [[ATTR0]] = { {{.*}} } // DARWIN: attributes [[ATTR1]] = { {{.*}}nounwind{{.*}}"target-features"{{.*}} } diff --git a/clang/test/Driver/aix-shared-lib-tls-model-opt.c b/clang/test/Driver/aix-shared-lib-tls-model-opt.c index 7acf091f0a049..891caf4ed3fcd 100644 --- a/clang/test/Driver/aix-shared-lib-tls-model-opt.c +++ b/clang/test/Driver/aix-shared-lib-tls-model-opt.c @@ -1,5 +1,5 @@ -// RUN: %clang -target powerpc64-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK-AIX,CHECK-AIX-OFF %s -// RUN: %clang -target powerpc-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK-AIX,CHECK-AIX-OFF %s +// RUN: %clang -target powerpc64-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-AIX %s +// RUN: %clang -target powerpc-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-AIX %s // RUN: %clang -target powerpc64le-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LINUX %s // RUN: %clang -target powerpc64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LINUX %s @@ -19,9 +19,8 @@ int test(void) { // CHECK-AIX: test() #0 { // CHECK-AIX: attributes #0 = { -// CHECK-AIX-OFF-SAME: -aix-shared-lib-tls-model-opt // CHECK-AIX-ON-SAME: +aix-shared-lib-tls-model-opt -// CHECK-LINUX-NOT: {{[-+]aix-shared-lib-tls-model-opt}} +// CHECK-LINUX-NOT: {{[+]aix-shared-lib-tls-model-opt}} // CHECK-UNSUPPORTED-TARGET: option '-maix-shared-lib-tls-model-opt' cannot be specified on this target diff --git a/clang/test/Driver/aix-small-local-exec-dynamic-tls.c b/clang/test/Driver/aix-small-local-exec-dynamic-tls.c index 1a0619b58e891..87250382f2357 100644 --- a/clang/test/Driver/aix-small-local-exec-dynamic-tls.c +++ b/clang/test/Driver/aix-small-local-exec-dynamic-tls.c @@ -1,7 +1,7 @@ -// RUN: %clang -target powerpc64-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-AIX-DEFAULT %s -// RUN: %clang -target powerpc-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-AIX-DEFAULT %s -// RUN: %clang -target powerpc64le-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LINUX %s -// RUN: %clang -target powerpc64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LINUX %s +// RUN: %clang -target powerpc64-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-DEFAULT %s +// RUN: %clang -target powerpc-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-DEFAULT %s +// RUN: %clang -target powerpc64le-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-DEFAULT %s +// RUN: %clang -target powerpc64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-DEFAULT %s // RUN: %clang -target powerpc64-unknown-aix -maix-small-local-exec-tls -S -emit-llvm \ // RUN: %s -o - | FileCheck %s --check-prefix=CHECK-AIX_SMALL_LOCALEXEC_TLS @@ -39,10 +39,9 @@ int test(void) { return 0; } -// CHECK-AIX-DEFAULT: test() #0 { -// CHECK-AIX-DEFAULT: attributes #0 = { -// CHECK-AIX-DEFAULT-SAME: {{-aix-small-local-exec-tls,.*-aix-small-local-dynamic-tls|-aix-small-local-dynamic-tls,.*-aix-small-local-exec-tls}} -// CHECK-LINUX-NOT: {{[-+]aix-small-local-exec-tls,.*[-+]aix-small-local-dynamic-tls|[-+]aix-small-local-dynamic-tls,.*[-+]aix-small-local-exec-tls}} +// CHECK-DEFAULT: test() #0 { +// CHECK-DEFAULT: attributes #0 = { +// CHECK-DEFAULT-NOT: {{[-+]aix-small-local-exec-tls,.*[-+]aix-small-local-dynamic-tls|[-+]aix-small-local-dynamic-tls,.*[-+]aix-small-local-exec-tls}} // CHECK-UNSUPPORTED-AIX32: option '-maix-small-local-[exec|dynamic]-tls' cannot be specified on this target // CHECK-UNSUPPORTED-LINUX: option '-maix-small-local-[exec|dynamic]-tls' cannot be specified on this target diff --git a/clang/test/Driver/ppc-crbits.cpp b/clang/test/Driver/ppc-crbits.cpp index 3ed56308cb526..62893d3d0e87d 100644 --- a/clang/test/Driver/ppc-crbits.cpp +++ b/clang/test/Driver/ppc-crbits.cpp @@ -64,8 +64,6 @@ // RUN: %clang -target powerpc64le-unknown-linux-gnu -mcpu=pwr8 -mno-crbits \ // RUN: -emit-llvm -S %s -o - | FileCheck %s --check-prefix=HAS-NOCRBITS -// RUN: %clang -target powerpc64le-unknown-linux-gnu -mcpu=pwr7 -emit-llvm \ -// RUN: -S %s -o - | FileCheck %s --check-prefix=HAS-NOCRBITS // RUN: %clang -target powerpc64le-unknown-linux-gnu -mcpu=pwr7 -mcrbits \ // RUN: -emit-llvm -S %s -o - | FileCheck %s --check-prefix=HAS-CRBITS // RUN: %clang -target powerpc64le-unknown-linux-gnu -mcpu=pwr7 -mno-crbits \ @@ -92,8 +90,6 @@ // RUN: %clang -target powerpc-ibm-aix -mcpu=pwr8 -mno-crbits \ // RUN: -emit-llvm -S %s -o - | FileCheck %s --check-prefix=HAS-NOCRBITS -// RUN: %clang -target powerpc-ibm-aix -mcpu=pwr7 -emit-llvm \ -// RUN: -S %s -o - | FileCheck %s --check-prefix=HAS-NOCRBITS // RUN: %clang -target powerpc-ibm-aix -mcpu=pwr7 -mcrbits \ // RUN: -emit-llvm -S %s -o - | FileCheck %s --check-prefix=HAS-CRBITS // RUN: %clang -target powerpc-ibm-aix -mcpu=pwr7 -mno-crbits \ diff --git a/clang/test/Driver/ppc-isa-features.cpp b/clang/test/Driver/ppc-isa-features.cpp index 92c5bc82f72b8..35dbfbcdf5699 100644 --- a/clang/test/Driver/ppc-isa-features.cpp +++ b/clang/test/Driver/ppc-isa-features.cpp @@ -5,20 +5,20 @@ // RUN: %clang -target powerpc64-unknown-aix -mcpu=pwr9 -S -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-PWR9 // RUN: %clang -target powerpc-unknown-aix -mcpu=pwr10 -S -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-PWR10 -// CHECK-PWR6: -isa-v206-instructions -// CHECK-PWR6: -isa-v207-instructions -// CHECK-PWR6: -isa-v30-instructions +// CHECK-PWR6-NOT: isa-v206-instructions +// CHECK-PWR6-NOT: isa-v207-instructions +// CHECK-PWR6-NOT: isa-v30-instructions -// CHECK-A2: +isa-v206-instructions -// CHECK-A2: -isa-v207-instructions -// CHECK-A2: -isa-v30-instructions +// CHECK-A2: +isa-v206-instructions +// CHECK-A2-NOT: isa-v207-instructions +// CHECK-A2-NOT: isa-v30-instructions -// CHECK-PWR7: +isa-v206-instructions -// CHECK-PWR7: -isa-v207-instructions -// CHECK-PWR7: -isa-v30-instructions +// CHECK-PWR7: +isa-v206-instructions +// CHECK-PWR7-NOT: isa-v207-instructions +// CHECK-PWR7-NOT: isa-v30-instructions -// CHECK-PWR8: +isa-v207-instructions -// CHECK-PWR8: -isa-v30-instructions +// CHECK-PWR8: +isa-v207-instructions +// CHECK-PWR8-NOT: isa-v30-instructions // CHECK-PWR9: +isa-v207-instructions // CHECK-PWR9: +isa-v30-instructions diff --git a/llvm/include/llvm/MC/MCSubtargetInfo.h b/llvm/include/llvm/MC/MCSubtargetInfo.h index 535bcfe2fb6d7..287aaf591c107 100644 --- a/llvm/include/llvm/MC/MCSubtargetInfo.h +++ b/llvm/include/llvm/MC/MCSubtargetInfo.h @@ -15,6 +15,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/MC/MCSchedule.h" @@ -32,9 +33,8 @@ class MCInst; //===----------------------------------------------------------------------===// /// Used to provide key value pairs for feature and CPU bit flags. -struct SubtargetFeatureKV { +struct BasicSubtargetFeatureKV { const char *Key; ///< K-V key string - const char *Desc; ///< Help descriptor unsigned Value; ///< K-V integer value FeatureBitArray Implies; ///< K-V bit mask @@ -44,19 +44,27 @@ struct SubtargetFeatureKV { } /// Compare routine for std::is_sorted. - bool operator<(const SubtargetFeatureKV &Other) const { + bool operator<(const BasicSubtargetFeatureKV &Other) const { return StringRef(Key) < StringRef(Other.Key); } + BasicSubtargetFeatureKV(const char *Key, unsigned Value, + FeatureBitArray Implies) + : Key(Key), Value(Value), Implies(Implies) {} +}; + +struct SubtargetFeatureKV : BasicSubtargetFeatureKV { + const char *Desc; ///< Help descriptor + SubtargetFeatureKV(const char *Key, const char *Desc, unsigned Value, + FeatureBitArray Implies) + : BasicSubtargetFeatureKV(Key, Value, Implies), Desc(Desc) {} }; //===----------------------------------------------------------------------===// /// Used to provide key value pairs for feature and CPU bit flags. -struct SubtargetSubTypeKV { +struct BasicSubtargetSubTypeKV { const char *Key; ///< K-V key string FeatureBitArray Implies; ///< K-V bit mask - FeatureBitArray TuneImplies; ///< K-V bit mask - const MCSchedModel *SchedModel; /// Compare routine for std::lower_bound bool operator<(StringRef S) const { @@ -64,11 +72,21 @@ struct SubtargetSubTypeKV { } /// Compare routine for std::is_sorted. - bool operator<(const SubtargetSubTypeKV &Other) const { + bool operator<(const BasicSubtargetSubTypeKV &Other) const { return StringRef(Key) < StringRef(Other.Key); } }; +struct SubtargetSubTypeKV : BasicSubtargetSubTypeKV { + FeatureBitArray TuneImplies; ///< K-V bit mask + const MCSchedModel *SchedModel; +}; + +std::optional<llvm::StringMap<bool>> +getCPUDefaultTargetFeatures(StringRef CPU, + ArrayRef<BasicSubtargetSubTypeKV> ProcDesc, + ArrayRef<BasicSubtargetFeatureKV> ProcFeatures); + //===----------------------------------------------------------------------===// /// /// Generic base class for all target subtargets. diff --git a/llvm/include/llvm/TargetParser/PPCTargetParser.h b/llvm/include/llvm/TargetParser/PPCTargetParser.h index 5f9fe543aff0b..9018d6b919ebb 100644 --- a/llvm/include/llvm/TargetParser/PPCTargetParser.h +++ b/llvm/include/llvm/TargetParser/PPCTargetParser.h @@ -14,7 +14,9 @@ #ifndef LLVM_TARGETPARSER_PPCTARGETPARSER_H #define LLVM_TARGETPARSER_PPCTARGETPARSER_H +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/TargetParser/Triple.h" namespace llvm { @@ -34,6 +36,9 @@ StringRef getNormalizedPPCTuneCPU(const Triple &T, StringRef CPUName = ""); // For PPC, there are some cpu names for same CPU, like pwr10 and power10, // normalize them. StringRef normalizeCPUName(StringRef CPUName); + +std::optional<llvm::StringMap<bool>> +getPPCDefaultTargetFeatures(const Triple &T, StringRef CPUName); } // namespace PPC } // namespace llvm diff --git a/llvm/lib/MC/MCSubtargetInfo.cpp b/llvm/lib/MC/MCSubtargetInfo.cpp index d86eaad48420d..410ca55a53646 100644 --- a/llvm/lib/MC/MCSubtargetInfo.cpp +++ b/llvm/lib/MC/MCSubtargetInfo.cpp @@ -33,13 +33,13 @@ static const T *Find(StringRef S, ArrayRef<T> A) { } /// For each feature that is (transitively) implied by this feature, set it. -static -void SetImpliedBits(FeatureBitset &Bits, const FeatureBitset &Implies, - ArrayRef<SubtargetFeatureKV> FeatureTable) { +template <typename FeatureKVType> +static void SetImpliedBits(FeatureBitset &Bits, const FeatureBitset &Implies, + ArrayRef<FeatureKVType> FeatureTable) { // OR the Implies bits in outside the loop. This allows the Implies for CPUs // which might imply features not in FeatureTable to use this. Bits |= Implies; - for (const SubtargetFeatureKV &FE : FeatureTable) + for (const FeatureKVType &FE : FeatureTable) if (Implies.test(FE.Value)) SetImpliedBits(Bits, FE.Implies.getAsBitset(), FeatureTable); } @@ -226,6 +226,30 @@ static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, return Bits; } +std::optional<llvm::StringMap<bool>> llvm::getCPUDefaultTargetFeatures( + StringRef CPU, ArrayRef<BasicSubtargetSubTypeKV> ProcDesc, + ArrayRef<BasicSubtargetFeatureKV> ProcFeatures) { + if (CPU.empty()) + return std::nullopt; + + const BasicSubtargetSubTypeKV *CPUEntry = Find(CPU, ProcDesc); + if (!CPUEntry) + return std::nullopt; + + // Set the features implied by this CPU feature if there is a match. + FeatureBitset Bits; + llvm::StringMap<bool> DefaultFeatures; + SetImpliedBits(Bits, CPUEntry->Implies.getAsBitset(), ProcFeatures); + + unsigned BitSize = Bits.size(); + for (const BasicSubtargetFeatureKV &FE : ProcFeatures) { + assert(FE.Value < BitSize && "Target Feature is out of range"); + if (Bits[FE.Value]) + DefaultFeatures[FE.Key] = true; + } + return DefaultFeatures; +} + void MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef TuneCPU, StringRef FS) { FeatureBits = diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td index 39da428461393..8e1204d574db0 100644 --- a/llvm/lib/Target/PowerPC/PPC.td +++ b/llvm/lib/Target/PowerPC/PPC.td @@ -411,7 +411,6 @@ def ProcessorFeatures { FeatureP8Altivec, FeatureP8Vector, FeatureP8Crypto, - FeatureHTM, FeatureDirectMove, FeatureICBT, FeaturePartwordAtomic, @@ -422,6 +421,7 @@ def ProcessorFeatures { ]; list<SubtargetFeature> P8SpecificFeatures = [FeatureAddiLoadFusion, + FeatureHTM, FeatureAddisLoadFusion]; list<SubtargetFeature> P8InheritableFeatures = !listconcat(P7InheritableFeatures, P8AdditionalFeatures); @@ -444,7 +444,7 @@ def ProcessorFeatures { // dispatch for vector operations than scalar ones. For the time being, // this list also includes scheduling-related features since we do not have // enough info to create custom scheduling strategies for future CPUs. - list<SubtargetFeature> P9SpecificFeatures = [FeatureVectorsUseTwoUnits]; + list<SubtargetFeature> P9SpecificFeatures = [FeatureVectorsUseTwoUnits,FeatureHTM]; list<SubtargetFeature> P9InheritableFeatures = !listconcat(P8InheritableFeatures, P9AdditionalFeatures); list<SubtargetFeature> P9Features = diff --git a/llvm/lib/TargetParser/CMakeLists.txt b/llvm/lib/TargetParser/CMakeLists.txt index 8ec32f7410566..543524be2f30e 100644 --- a/llvm/lib/TargetParser/CMakeLists.txt +++ b/llvm/lib/TargetParser/CMakeLists.txt @@ -8,6 +8,12 @@ if (HAS_WERROR_GLOBAL_CTORS AND NOT LLVM_HAS_NOGLOBAL_CTOR_MUTEX) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=global-constructors") endif() +set(LLVM_TARGET_DEFINITIONS ${LLVM_MAIN_SRC_DIR}/lib/Target/PowerPC/PPC.td) + +tablegen(LLVM PPCGenSubtargetInfo.inc -gen-subtarget -I${LLVM_MAIN_SRC_DIR}/lib/Target/PowerPC) +add_public_tablegen_target(PPCGenSubtargetInfo) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) # Solaris code uses kstat, so specify dependency explicitly for shared builds. if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") set(system_libs kstat) @@ -43,3 +49,5 @@ add_llvm_component_library(LLVMTargetParser AArch64TargetParserTableGen RISCVTargetParserTableGen ) + +add_dependencies(LLVMTargetParser PPCGenSubtargetInfo) diff --git a/llvm/lib/TargetParser/PPCTargetParser.cpp b/llvm/lib/TargetParser/PPCTargetParser.cpp index 422d758c772e1..bd460c7091fd3 100644 --- a/llvm/lib/TargetParser/PPCTargetParser.cpp +++ b/llvm/lib/TargetParser/PPCTargetParser.cpp @@ -15,6 +15,10 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/TargetParser/Host.h" +#define GET_SUBTARGETINFO_ENUM +#define GET_SUBTARGETFEATURES_KV +#include "PPCGenSubtargetInfo.inc" + namespace llvm { namespace PPC { @@ -117,5 +121,27 @@ StringRef getNormalizedPPCTuneCPU(const Triple &T, StringRef CPUName) { return getNormalizedPPCTargetCPU(T, CPUName); } +std::optional<StringMap<bool>> getPPCDefaultTargetFeatures(const Triple &T, + StringRef CPU) { + std::optional<StringMap<bool>> FeaturesOpt = + getCPUDefaultTargetFeatures(CPU, BasicPPCSubTypeKV, BasicPPCFeatureKV); + + if (!FeaturesOpt.has_value()) + return std::nullopt; + + StringMap<bool> Features = FeaturesOpt.value(); + // FIXME: We need to check for the processor model 8548, since the backend + // does not support this processor. When this processor model is implemented + // within the backend, the following code can be removed. + if (CPU == "8548") + Features["spe"] = true; + + // The target feature `quadword-atomics` is enabled by llvm back-end for + // power8 or power8 up, we disable the target feature if the triple is + // 32-bit. + if (Features.find("quadword-atomics") != Features.end() && !T.isArch64Bit()) + Features["quadword-atomics"] = false; + return Features; +} } // namespace PPC } // namespace llvm diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp index 8d2fc99f84670..be1409f651ef4 100644 --- a/llvm/utils/TableGen/SubtargetEmitter.cpp +++ b/llvm/utils/TableGen/SubtargetEmitter.cpp @@ -90,8 +90,10 @@ class SubtargetEmitter { FeatureMapTy enumeration(raw_ostream &OS); void emitSubtargetInfoMacroCalls(raw_ostream &OS); - unsigned featureKeyValues(raw_ostream &OS, const FeatureMapTy &FeatureMap); - unsigned cpuKeyValues(raw_ostream &OS, const FeatureMapTy &FeatureMap); + unsigned featureKeyValues(raw_ostream &OS, const FeatureMapTy &FeatureMap, + bool IsEmitBasic = false); + unsigned cpuKeyValues(raw_ostream &OS, const FeatureMapTy &FeatureMap, + bool IsEmitBasic = false); unsigned cpuNames(raw_ostream &OS); void formItineraryStageString(const std::string &Names, const Record *ItinData, std::string &ItinString, @@ -255,7 +257,8 @@ void SubtargetEmitter::emitSubtargetInfoMacroCalls(raw_ostream &OS) { // command line. // unsigned SubtargetEmitter::featureKeyValues(raw_ostream &OS, - const FeatureMapTy &FeatureMap) { + const FeatureMapTy &FeatureMap, + bool IsEmitBasic) { std::vector<const Record *> FeatureList = Records.getAllDerivedDefinitions("SubtargetFeature"); @@ -271,8 +274,8 @@ unsigned SubtargetEmitter::featureKeyValues(raw_ostream &OS, // Begin feature table. OS << "// Sorted (by key) array of values for CPU features.\n" - << "extern const llvm::SubtargetFeatureKV " << Target - << "FeatureKV[] = {\n"; + << "extern const llvm::" << (IsEmitBasic ? "Basic" : "") << "SubtargetFeatureKV " + << (IsEmitBasic ? "Basic" : "") << Target << "FeatureKV[] = {\n"; for (const Record *Feature : FeatureList) { // Next feature @@ -282,9 +285,11 @@ unsigned SubtargetEmitter::featureKeyValues(raw_ostream &OS, // Emit as { "feature", "description", { featureEnum }, { i1 , i2 , ... , in // } } - OS << " { " - << "\"" << CommandLineName << "\", " - << "\"" << Desc << "\", " << Target << "::" << Name << ", "; + OS << " { " << "\"" << CommandLineName << "\", "; + if (!IsEmitBasic) + OS << "\"" << Desc << "\", "; + + OS << Target << "::" << Name << ", "; ConstRecVec ImpliesList = Feature->getValueAsListOfDefs("Implies"); @@ -338,7 +343,8 @@ unsigned SubtargetEmitter::cpuNames(raw_ostream &OS) { // line. // unsigned SubtargetEmitter::cpuKeyValues(raw_ostream &OS, - const FeatureMapTy &FeatureMap) { + const FeatureMapTy &FeatureMap, + bool IsEmitBasic) { // Gather and sort processor information std::vector<const Record *> ProcessorList = Records.getAllDerivedDefinitions("Processor"); @@ -351,8 +357,8 @@ unsigned SubtargetEmitter::cpuKeyValues(raw_ostream &OS, // Begin processor table. OS << "// Sorted (by key) array of values for CPU subtype.\n" - << "extern const llvm::SubtargetSubTypeKV " << Target - << "SubTypeKV[] = {\n"; + << "extern const llvm::" << (IsEmitBasic ? "Basic" : "") << "SubtargetSubTypeKV " + << (IsEmitBasic ? "Basic" : "") << Target << "SubTypeKV[] = {\n"; for (const Record *Processor : ProcessorList) { StringRef Name = Processor->getValueAsString("Name"); @@ -365,13 +371,17 @@ unsigned SubtargetEmitter::cpuKeyValues(raw_ostream &OS, << "\"" << Name << "\", "; printFeatureMask(OS, FeatureList, FeatureMap); - OS << ", "; - printFeatureMask(OS, TuneFeatureList, FeatureMap); - // Emit the scheduler model pointer. - const std::string &ProcModelName = - SchedModels.getModelForProc(Processor).ModelName; - OS << ", &" << ProcModelName << " },\n"; + if (!IsEmitBasic) { + OS << ", "; + printFeatureMask(OS, TuneFeatureList, FeatureMap); + + // Emit the scheduler model pointer. + const std::string &ProcModelName = + SchedModels.getModelForProc(Processor).ModelName; + OS << ", &" << ProcModelName; + } + OS << " },\n"; } // End processor table. @@ -2013,6 +2023,14 @@ void SubtargetEmitter::run(raw_ostream &OS) { OS << "} // end namespace llvm\n\n"; OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n"; + OS << "\n#ifdef GET_SUBTARGETFEATURES_KV\n"; + OS << "#undef GET_SUBTARGETFEATURES_KV\n\n"; + OS << "namespace llvm {\n"; + featureKeyValues(OS, FeatureMap, true); + cpuKeyValues(OS, FeatureMap, true); + OS << "} // end namespace llvm\n\n"; + OS << "#endif // GET_SUBTARGETFEATURES_KV\n\n"; + emitSubtargetInfoMacroCalls(OS); OS << "namespace llvm {\n"; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits