forked from OSchip/llvm-project
Introduce TargetInfo::hasFeature() to query various feature names in
each of the targets. Use this for module requirements, so that we can pin the availability of certain modules to certain target features, e.g., provide a module for xmmintrin.h only when SSE support is available. Use these feature names to provide a nearly-complete module map for Clang's built-in headers. Only mm_alloc.h and unwind.h are missing, and those two are fairly specialized at the moment. Finishes <rdar://problem/10710060>. llvm-svn: 149227
This commit is contained in:
parent
978fe0c75a
commit
0070c0bfbe
|
@ -601,6 +601,11 @@ public:
|
|||
virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
|
||||
}
|
||||
|
||||
/// \brief Determine whether the given target has the given feature.
|
||||
virtual bool hasFeature(StringRef Feature) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// getRegParmMax - Returns maximal number of args passed in registers.
|
||||
unsigned getRegParmMax() const {
|
||||
assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle");
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "clang/Basic/Module.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
@ -50,12 +51,15 @@ Module::~Module() {
|
|||
static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
|
||||
const TargetInfo &Target) {
|
||||
return llvm::StringSwitch<bool>(Feature)
|
||||
.Case("altivec", LangOpts.AltiVec)
|
||||
.Case("blocks", LangOpts.Blocks)
|
||||
.Case("cplusplus", LangOpts.CPlusPlus)
|
||||
.Case("cplusplus11", LangOpts.CPlusPlus0x)
|
||||
.Case("objc", LangOpts.ObjC1)
|
||||
.Case("objc_arc", LangOpts.ObjCAutoRefCount)
|
||||
.Default(false);
|
||||
.Case("opencl", LangOpts.OpenCL)
|
||||
.Case("tls", Target.isTLSSupported())
|
||||
.Default(Target.hasFeature(Feature));
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -583,6 +583,8 @@ public:
|
|||
virtual void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const;
|
||||
|
||||
virtual bool hasFeature(StringRef Feature) const;
|
||||
|
||||
virtual void getGCCRegNames(const char * const *&Names,
|
||||
unsigned &NumNames) const;
|
||||
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
||||
|
@ -735,7 +737,11 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
|
|||
}
|
||||
}
|
||||
|
||||
bool PPCTargetInfo::hasFeature(StringRef Feature) const {
|
||||
return Feature == "powerpc";
|
||||
}
|
||||
|
||||
|
||||
const char * const PPCTargetInfo::GCCRegNames[] = {
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||
|
@ -964,7 +970,10 @@ namespace {
|
|||
Records = BuiltinInfo;
|
||||
NumRecords = clang::PTX::LastTSBuiltin-Builtin::FirstTSBuiltin;
|
||||
}
|
||||
|
||||
virtual bool hasFeature(StringRef Feature) const {
|
||||
return Feature == "ptx";
|
||||
}
|
||||
|
||||
virtual void getGCCRegNames(const char * const *&Names,
|
||||
unsigned &NumNames) const;
|
||||
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
||||
|
@ -1063,6 +1072,10 @@ public:
|
|||
virtual void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const;
|
||||
|
||||
virtual bool hasFeature(StringRef Feature) const {
|
||||
return Feature == "mblaze";
|
||||
}
|
||||
|
||||
virtual const char *getVAListDeclaration() const {
|
||||
return "typedef char* __builtin_va_list;";
|
||||
}
|
||||
|
@ -1402,6 +1415,7 @@ public:
|
|||
const std::string &Name,
|
||||
bool Enabled) const;
|
||||
virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
|
||||
virtual bool hasFeature(StringRef Feature) const;
|
||||
virtual void HandleTargetFeatures(std::vector<std::string> &Features);
|
||||
virtual const char* getABI() const {
|
||||
if (PointerWidth == 64 && SSELevel >= AVX)
|
||||
|
@ -2072,6 +2086,30 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
|
|||
}
|
||||
}
|
||||
|
||||
bool X86TargetInfo::hasFeature(StringRef Feature) const {
|
||||
return llvm::StringSwitch<bool>(Feature)
|
||||
.Case("aes", HasAES)
|
||||
.Case("avx", SSELevel >= AVX)
|
||||
.Case("avx2", SSELevel >= AVX2)
|
||||
.Case("bmi", HasBMI)
|
||||
.Case("bmi2", HasBMI2)
|
||||
.Case("fma4", HasFMA4)
|
||||
.Case("lzcnt", HasLZCNT)
|
||||
.Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
|
||||
.Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
|
||||
.Case("mmx", MMX3DNowLevel >= MMX)
|
||||
.Case("popcnt", HasPOPCNT)
|
||||
.Case("sse", SSELevel >= SSE1)
|
||||
.Case("sse2", SSELevel >= SSE2)
|
||||
.Case("sse3", SSELevel >= SSE3)
|
||||
.Case("ssse3", SSELevel >= SSSE3)
|
||||
.Case("sse41", SSELevel >= SSE41)
|
||||
.Case("sse42", SSELevel >= SSE42)
|
||||
.Case("x86", true)
|
||||
.Case("x86_32", PointerWidth == 32)
|
||||
.Case("x86_64", PointerWidth == 64)
|
||||
.Default(false);
|
||||
}
|
||||
|
||||
bool
|
||||
X86TargetInfo::validateAsmConstraint(const char *&Name,
|
||||
|
@ -2702,6 +2740,15 @@ public:
|
|||
Features.erase(it);
|
||||
}
|
||||
|
||||
virtual bool hasFeature(StringRef Feature) const {
|
||||
return llvm::StringSwitch<bool>(Feature)
|
||||
.Case("arm", true)
|
||||
.Case("softfloat", SoftFloat)
|
||||
.Case("thumb", IsThumb)
|
||||
.Case("neon", FPU == NeonFPU && !SoftFloat &&
|
||||
StringRef(getCPUDefineSuffix(CPU)).startswith("7"))
|
||||
.Default(false);
|
||||
}
|
||||
static const char *getCPUDefineSuffix(StringRef Name) {
|
||||
return llvm::StringSwitch<const char*>(Name)
|
||||
.Cases("arm8", "arm810", "4")
|
||||
|
@ -2964,6 +3011,10 @@ public:
|
|||
virtual void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const;
|
||||
|
||||
virtual bool hasFeature(StringRef Feature) const {
|
||||
return Feature == "hexagon";
|
||||
}
|
||||
|
||||
virtual const char *getVAListDeclaration() const {
|
||||
return "typedef char* __builtin_va_list;";
|
||||
}
|
||||
|
@ -3111,6 +3162,14 @@ public:
|
|||
if (SoftFloat)
|
||||
Builder.defineMacro("SOFT_FLOAT", "1");
|
||||
}
|
||||
|
||||
virtual bool hasFeature(StringRef Feature) const {
|
||||
return llvm::StringSwitch<bool>(Feature)
|
||||
.Case("softfloat", SoftFloat)
|
||||
.Case("sparc", true)
|
||||
.Default(false);
|
||||
}
|
||||
|
||||
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
||||
unsigned &NumRecords) const {
|
||||
// FIXME: Implement!
|
||||
|
@ -3239,6 +3298,9 @@ namespace {
|
|||
Records = 0;
|
||||
NumRecords = 0;
|
||||
}
|
||||
virtual bool hasFeature(StringRef Feature) const {
|
||||
return Feature == "msp430";
|
||||
}
|
||||
virtual void getGCCRegNames(const char * const *&Names,
|
||||
unsigned &NumNames) const;
|
||||
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
||||
|
@ -3328,6 +3390,10 @@ namespace {
|
|||
Builder.defineMacro("__TCE__");
|
||||
Builder.defineMacro("__TCE_V1__");
|
||||
}
|
||||
virtual bool hasFeature(StringRef Feature) const {
|
||||
return Feature == "tce";
|
||||
}
|
||||
|
||||
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
||||
unsigned &NumRecords) const {}
|
||||
virtual const char *getClobbers() const {
|
||||
|
@ -3373,6 +3439,9 @@ public:
|
|||
unsigned &NumRecords) const {
|
||||
// FIXME: Implement!
|
||||
}
|
||||
virtual bool hasFeature(StringRef Feature) const {
|
||||
return Feature == "mips";
|
||||
}
|
||||
virtual const char *getVAListDeclaration() const {
|
||||
return "typedef void* __builtin_va_list;";
|
||||
}
|
||||
|
@ -3699,6 +3768,9 @@ public:
|
|||
Builder.defineMacro("__native_client__");
|
||||
getArchDefines(Opts, Builder);
|
||||
}
|
||||
virtual bool hasFeature(StringRef Feature) const {
|
||||
return Feature == "pnacl";
|
||||
}
|
||||
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
||||
unsigned &NumRecords) const {
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
module __compiler_builtins [system] {
|
||||
explicit module altivec {
|
||||
requires altivec
|
||||
header "altivec.h"
|
||||
}
|
||||
|
||||
explicit module float_constants {
|
||||
header "float.h"
|
||||
}
|
||||
|
@ -35,5 +40,106 @@ module __compiler_builtins [system] {
|
|||
header "tgmath.h"
|
||||
}
|
||||
|
||||
// FIXME: add various altivec, *intrin headers.
|
||||
explicit module intel {
|
||||
requires x86
|
||||
|
||||
header "immintrin.h"
|
||||
header "x86intrin.h"
|
||||
|
||||
explicit module cpuid {
|
||||
header "cpuid.h"
|
||||
}
|
||||
|
||||
explicit module mmx {
|
||||
requires mmx
|
||||
header "mmintrin.h"
|
||||
}
|
||||
|
||||
explicit module sse {
|
||||
requires sse
|
||||
export mmx
|
||||
header "xmmintrin.h"
|
||||
}
|
||||
|
||||
explicit module sse2 {
|
||||
requires sse2
|
||||
export sse
|
||||
header "emmintrin.h"
|
||||
}
|
||||
|
||||
explicit module sse3 {
|
||||
requires sse3
|
||||
export sse2
|
||||
header "pmmintrin.h"
|
||||
}
|
||||
|
||||
explicit module ssse3 {
|
||||
requires ssse3
|
||||
export sse3
|
||||
header "tmmintrin.h"
|
||||
}
|
||||
|
||||
explicit module sse4_1 {
|
||||
requires sse41
|
||||
export ssse3
|
||||
header "smmintrin.h"
|
||||
}
|
||||
|
||||
explicit module sse4_2 {
|
||||
requires sse42
|
||||
export sse4_1
|
||||
header "nmmintrin.h"
|
||||
}
|
||||
|
||||
explicit module avx {
|
||||
requires avx
|
||||
export sse4_2
|
||||
header "avxintrin.h"
|
||||
}
|
||||
|
||||
explicit module avx2 {
|
||||
requires avx2
|
||||
export acx
|
||||
header "avx2intrin.h"
|
||||
}
|
||||
|
||||
explicit module bmi {
|
||||
requires bmi
|
||||
header "bmiintrin.h"
|
||||
}
|
||||
|
||||
explicit module bmi2 {
|
||||
requires bmi2
|
||||
header "bmi2intrin.h"
|
||||
}
|
||||
|
||||
explicit module fma4 {
|
||||
requires fma4
|
||||
export sse3
|
||||
header "fma4intrin.h"
|
||||
}
|
||||
|
||||
explicit module lzcnt {
|
||||
requires lzcnt
|
||||
header "lzcntintrin.h"
|
||||
}
|
||||
|
||||
explicit module popcnt {
|
||||
requires popcnt
|
||||
header "popcntintrin.h"
|
||||
}
|
||||
|
||||
explicit module mm3dnow {
|
||||
requires mm3dnow
|
||||
header "mm3dnow.h"
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: mm_malloc.h
|
||||
// FIXME: unwind.h
|
||||
|
||||
explicit module varargs {
|
||||
requires unavailable
|
||||
header "varargs.h"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,3 +13,11 @@ float getFltMax() { return FLT_MAX; }
|
|||
char getCharMax() { return CHAR_MAX; }
|
||||
|
||||
size_t size; // expected-error{{unknown type name 'size_t'}}
|
||||
|
||||
#ifdef __SSE__
|
||||
@import __compiler_builtins.intel.sse;
|
||||
#endif
|
||||
|
||||
#ifdef __AVX2__
|
||||
@import __compiler_builtins.intel.avx2;
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue