diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /clang/lib/Basic | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) | |
download | src-cfca06d7963fa0909f90483b42a6d7d194d01e08.tar.gz src-cfca06d7963fa0909f90483b42a6d7d194d01e08.zip |
Notes
Diffstat (limited to 'clang/lib/Basic')
55 files changed, 1880 insertions, 1858 deletions
diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp index 74cc3d1d03da..ff6dbf870fcf 100644 --- a/clang/lib/Basic/Attributes.cpp +++ b/clang/lib/Basic/Attributes.cpp @@ -36,10 +36,14 @@ const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) { } static StringRef -normalizeAttrScopeName(StringRef ScopeName, +normalizeAttrScopeName(const IdentifierInfo *Scope, AttributeCommonInfo::Syntax SyntaxUsed) { + if (!Scope) + return ""; + // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name // to be "clang". + StringRef ScopeName = Scope->getName(); if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 || SyntaxUsed == AttributeCommonInfo::AS_C2x) { if (ScopeName == "__gnu__") @@ -50,7 +54,7 @@ normalizeAttrScopeName(StringRef ScopeName, return ScopeName; } -static StringRef normalizeAttrName(StringRef AttrName, +static StringRef normalizeAttrName(const IdentifierInfo *Name, StringRef NormalizedScopeName, AttributeCommonInfo::Syntax SyntaxUsed) { // Normalize the attribute name, __foo__ becomes foo. This is only allowable @@ -61,6 +65,7 @@ static StringRef normalizeAttrName(StringRef AttrName, SyntaxUsed == AttributeCommonInfo::AS_C2x) && (NormalizedScopeName.empty() || NormalizedScopeName == "gnu" || NormalizedScopeName == "clang")); + StringRef AttrName = Name->getName(); if (ShouldNormalize && AttrName.size() >= 4 && AttrName.startswith("__") && AttrName.endswith("__")) AttrName = AttrName.slice(2, AttrName.size() - 2); @@ -74,35 +79,41 @@ bool AttributeCommonInfo::isGNUScope() const { #include "clang/Sema/AttrParsedAttrKinds.inc" +static SmallString<64> normalizeName(const IdentifierInfo *Name, + const IdentifierInfo *Scope, + AttributeCommonInfo::Syntax SyntaxUsed) { + StringRef ScopeName = normalizeAttrScopeName(Scope, SyntaxUsed); + StringRef AttrName = normalizeAttrName(Name, ScopeName, SyntaxUsed); + + SmallString<64> FullName = ScopeName; + if (!ScopeName.empty()) { + assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 || + SyntaxUsed == AttributeCommonInfo::AS_C2x); + FullName += "::"; + } + FullName += AttrName; + + return FullName; +} + AttributeCommonInfo::Kind AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name, const IdentifierInfo *ScopeName, Syntax SyntaxUsed) { - StringRef AttrName = Name->getName(); - - SmallString<64> FullName; - if (ScopeName) - FullName += normalizeAttrScopeName(ScopeName->getName(), SyntaxUsed); - - AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed); - - // Ensure that in the case of C++11 attributes, we look for '::foo' if it is - // unscoped. - if (ScopeName || SyntaxUsed == AS_CXX11 || SyntaxUsed == AS_C2x) - FullName += "::"; - FullName += AttrName; + return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed); +} - return ::getAttrKind(FullName, SyntaxUsed); +std::string AttributeCommonInfo::getNormalizedFullName() const { + return static_cast<std::string>( + normalizeName(getAttrName(), getScopeName(), getSyntax())); } unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const { // Both variables will be used in tablegen generated // attribute spell list index matching code. auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax()); - StringRef Scope = - getScopeName() ? normalizeAttrScopeName(getScopeName()->getName(), Syntax) - : ""; - StringRef Name = normalizeAttrName(getAttrName()->getName(), Scope, Syntax); + StringRef Scope = normalizeAttrScopeName(getScopeName(), Syntax); + StringRef Name = normalizeAttrName(getAttrName(), Scope, Syntax); #include "clang/Sema/AttrSpellingListIndex.inc" } diff --git a/clang/lib/Basic/CodeGenOptions.cpp b/clang/lib/Basic/CodeGenOptions.cpp index fa186380f109..4fc7a535c9eb 100644 --- a/clang/lib/Basic/CodeGenOptions.cpp +++ b/clang/lib/Basic/CodeGenOptions.cpp @@ -17,7 +17,7 @@ CodeGenOptions::CodeGenOptions() { #include "clang/Basic/CodeGenOptions.def" RelocationModel = llvm::Reloc::PIC_; - memcpy(CoverageVersion, "402*", 4); + memcpy(CoverageVersion, "408*", 4); } bool CodeGenOptions::isNoBuiltinFunc(const char *Name) const { diff --git a/clang/lib/Basic/Cuda.cpp b/clang/lib/Basic/Cuda.cpp index f2b6c8cd3ee9..709185707bd9 100644 --- a/clang/lib/Basic/Cuda.cpp +++ b/clang/lib/Basic/Cuda.cpp @@ -2,6 +2,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/VersionTuple.h" @@ -27,12 +28,16 @@ const char *CudaVersionToString(CudaVersion V) { return "10.0"; case CudaVersion::CUDA_101: return "10.1"; + case CudaVersion::CUDA_102: + return "10.2"; + case CudaVersion::CUDA_110: + return "11.0"; } llvm_unreachable("invalid enum"); } -CudaVersion CudaStringToVersion(llvm::StringRef S) { - return llvm::StringSwitch<CudaVersion>(S) +CudaVersion CudaStringToVersion(const llvm::Twine &S) { + return llvm::StringSwitch<CudaVersion>(S.str()) .Case("7.0", CudaVersion::CUDA_70) .Case("7.5", CudaVersion::CUDA_75) .Case("8.0", CudaVersion::CUDA_80) @@ -40,253 +45,88 @@ CudaVersion CudaStringToVersion(llvm::StringRef S) { .Case("9.1", CudaVersion::CUDA_91) .Case("9.2", CudaVersion::CUDA_92) .Case("10.0", CudaVersion::CUDA_100) - .Case("10.1", CudaVersion::CUDA_101); + .Case("10.1", CudaVersion::CUDA_101) + .Case("10.2", CudaVersion::CUDA_102) + .Case("11.0", CudaVersion::CUDA_110) + .Default(CudaVersion::UNKNOWN); } -const char *CudaArchToString(CudaArch A) { - switch (A) { - case CudaArch::LAST: - break; - case CudaArch::UNKNOWN: - return "unknown"; - case CudaArch::SM_20: - return "sm_20"; - case CudaArch::SM_21: - return "sm_21"; - case CudaArch::SM_30: - return "sm_30"; - case CudaArch::SM_32: - return "sm_32"; - case CudaArch::SM_35: - return "sm_35"; - case CudaArch::SM_37: - return "sm_37"; - case CudaArch::SM_50: - return "sm_50"; - case CudaArch::SM_52: - return "sm_52"; - case CudaArch::SM_53: - return "sm_53"; - case CudaArch::SM_60: - return "sm_60"; - case CudaArch::SM_61: - return "sm_61"; - case CudaArch::SM_62: - return "sm_62"; - case CudaArch::SM_70: - return "sm_70"; - case CudaArch::SM_72: - return "sm_72"; - case CudaArch::SM_75: - return "sm_75"; - case CudaArch::GFX600: // tahiti - return "gfx600"; - case CudaArch::GFX601: // pitcairn, verde, oland,hainan - return "gfx601"; - case CudaArch::GFX700: // kaveri - return "gfx700"; - case CudaArch::GFX701: // hawaii - return "gfx701"; - case CudaArch::GFX702: // 290,290x,R390,R390x - return "gfx702"; - case CudaArch::GFX703: // kabini mullins - return "gfx703"; - case CudaArch::GFX704: // bonaire - return "gfx704"; - case CudaArch::GFX801: // carrizo - return "gfx801"; - case CudaArch::GFX802: // tonga,iceland - return "gfx802"; - case CudaArch::GFX803: // fiji,polaris10 - return "gfx803"; - case CudaArch::GFX810: // stoney - return "gfx810"; - case CudaArch::GFX900: // vega, instinct - return "gfx900"; - case CudaArch::GFX902: // TBA - return "gfx902"; - case CudaArch::GFX904: // TBA - return "gfx904"; - case CudaArch::GFX906: // TBA - return "gfx906"; - case CudaArch::GFX908: // TBA - return "gfx908"; - case CudaArch::GFX909: // TBA - return "gfx909"; - case CudaArch::GFX1010: // TBA - return "gfx1010"; - case CudaArch::GFX1011: // TBA - return "gfx1011"; - case CudaArch::GFX1012: // TBA - return "gfx1012"; - } - llvm_unreachable("invalid enum"); -} +struct CudaArchToStringMap { + CudaArch arch; + const char *arch_name; + const char *virtual_arch_name; +}; -CudaArch StringToCudaArch(llvm::StringRef S) { - return llvm::StringSwitch<CudaArch>(S) - .Case("sm_20", CudaArch::SM_20) - .Case("sm_21", CudaArch::SM_21) - .Case("sm_30", CudaArch::SM_30) - .Case("sm_32", CudaArch::SM_32) - .Case("sm_35", CudaArch::SM_35) - .Case("sm_37", CudaArch::SM_37) - .Case("sm_50", CudaArch::SM_50) - .Case("sm_52", CudaArch::SM_52) - .Case("sm_53", CudaArch::SM_53) - .Case("sm_60", CudaArch::SM_60) - .Case("sm_61", CudaArch::SM_61) - .Case("sm_62", CudaArch::SM_62) - .Case("sm_70", CudaArch::SM_70) - .Case("sm_72", CudaArch::SM_72) - .Case("sm_75", CudaArch::SM_75) - .Case("gfx600", CudaArch::GFX600) - .Case("gfx601", CudaArch::GFX601) - .Case("gfx700", CudaArch::GFX700) - .Case("gfx701", CudaArch::GFX701) - .Case("gfx702", CudaArch::GFX702) - .Case("gfx703", CudaArch::GFX703) - .Case("gfx704", CudaArch::GFX704) - .Case("gfx801", CudaArch::GFX801) - .Case("gfx802", CudaArch::GFX802) - .Case("gfx803", CudaArch::GFX803) - .Case("gfx810", CudaArch::GFX810) - .Case("gfx900", CudaArch::GFX900) - .Case("gfx902", CudaArch::GFX902) - .Case("gfx904", CudaArch::GFX904) - .Case("gfx906", CudaArch::GFX906) - .Case("gfx908", CudaArch::GFX908) - .Case("gfx909", CudaArch::GFX909) - .Case("gfx1010", CudaArch::GFX1010) - .Case("gfx1011", CudaArch::GFX1011) - .Case("gfx1012", CudaArch::GFX1012) - .Default(CudaArch::UNKNOWN); -} +#define SM2(sm, ca) \ + { CudaArch::SM_##sm, "sm_" #sm, ca } +#define SM(sm) SM2(sm, "compute_" #sm) +#define GFX(gpu) \ + { CudaArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn" } +CudaArchToStringMap arch_names[] = { + // clang-format off + SM2(20, "compute_20"), SM2(21, "compute_20"), // Fermi + SM(30), SM(32), SM(35), SM(37), // Kepler + SM(50), SM(52), SM(53), // Maxwell + SM(60), SM(61), SM(62), // Pascal + SM(70), SM(72), // Volta + SM(75), // Turing + SM(80), // Ampere + GFX(600), // tahiti + GFX(601), // pitcairn, verde, oland,hainan + GFX(700), // kaveri + GFX(701), // hawaii + GFX(702), // 290,290x,R390,R390x + GFX(703), // kabini mullins + GFX(704), // bonaire + GFX(801), // carrizo + GFX(802), // tonga,iceland + GFX(803), // fiji,polaris10 + GFX(810), // stoney + GFX(900), // vega, instinct + GFX(902), GFX(904), GFX(906), GFX(908), GFX(909), + GFX(1010), GFX(1011), GFX(1012), + // clang-format on +}; +#undef SM +#undef SM2 +#undef GFX -const char *CudaVirtualArchToString(CudaVirtualArch A) { - switch (A) { - case CudaVirtualArch::UNKNOWN: +const char *CudaArchToString(CudaArch A) { + auto result = std::find_if( + std::begin(arch_names), std::end(arch_names), + [A](const CudaArchToStringMap &map) { return A == map.arch; }); + if (result == std::end(arch_names)) return "unknown"; - case CudaVirtualArch::COMPUTE_20: - return "compute_20"; - case CudaVirtualArch::COMPUTE_30: - return "compute_30"; - case CudaVirtualArch::COMPUTE_32: - return "compute_32"; - case CudaVirtualArch::COMPUTE_35: - return "compute_35"; - case CudaVirtualArch::COMPUTE_37: - return "compute_37"; - case CudaVirtualArch::COMPUTE_50: - return "compute_50"; - case CudaVirtualArch::COMPUTE_52: - return "compute_52"; - case CudaVirtualArch::COMPUTE_53: - return "compute_53"; - case CudaVirtualArch::COMPUTE_60: - return "compute_60"; - case CudaVirtualArch::COMPUTE_61: - return "compute_61"; - case CudaVirtualArch::COMPUTE_62: - return "compute_62"; - case CudaVirtualArch::COMPUTE_70: - return "compute_70"; - case CudaVirtualArch::COMPUTE_72: - return "compute_72"; - case CudaVirtualArch::COMPUTE_75: - return "compute_75"; - case CudaVirtualArch::COMPUTE_AMDGCN: - return "compute_amdgcn"; - } - llvm_unreachable("invalid enum"); + return result->arch_name; } -CudaVirtualArch StringToCudaVirtualArch(llvm::StringRef S) { - return llvm::StringSwitch<CudaVirtualArch>(S) - .Case("compute_20", CudaVirtualArch::COMPUTE_20) - .Case("compute_30", CudaVirtualArch::COMPUTE_30) - .Case("compute_32", CudaVirtualArch::COMPUTE_32) - .Case("compute_35", CudaVirtualArch::COMPUTE_35) - .Case("compute_37", CudaVirtualArch::COMPUTE_37) - .Case("compute_50", CudaVirtualArch::COMPUTE_50) - .Case("compute_52", CudaVirtualArch::COMPUTE_52) - .Case("compute_53", CudaVirtualArch::COMPUTE_53) - .Case("compute_60", CudaVirtualArch::COMPUTE_60) - .Case("compute_61", CudaVirtualArch::COMPUTE_61) - .Case("compute_62", CudaVirtualArch::COMPUTE_62) - .Case("compute_70", CudaVirtualArch::COMPUTE_70) - .Case("compute_72", CudaVirtualArch::COMPUTE_72) - .Case("compute_75", CudaVirtualArch::COMPUTE_75) - .Case("compute_amdgcn", CudaVirtualArch::COMPUTE_AMDGCN) - .Default(CudaVirtualArch::UNKNOWN); +const char *CudaArchToVirtualArchString(CudaArch A) { + auto result = std::find_if( + std::begin(arch_names), std::end(arch_names), + [A](const CudaArchToStringMap &map) { return A == map.arch; }); + if (result == std::end(arch_names)) + return "unknown"; + return result->virtual_arch_name; } -CudaVirtualArch VirtualArchForCudaArch(CudaArch A) { - switch (A) { - case CudaArch::LAST: - break; - case CudaArch::UNKNOWN: - return CudaVirtualArch::UNKNOWN; - case CudaArch::SM_20: - case CudaArch::SM_21: - return CudaVirtualArch::COMPUTE_20; - case CudaArch::SM_30: - return CudaVirtualArch::COMPUTE_30; - case CudaArch::SM_32: - return CudaVirtualArch::COMPUTE_32; - case CudaArch::SM_35: - return CudaVirtualArch::COMPUTE_35; - case CudaArch::SM_37: - return CudaVirtualArch::COMPUTE_37; - case CudaArch::SM_50: - return CudaVirtualArch::COMPUTE_50; - case CudaArch::SM_52: - return CudaVirtualArch::COMPUTE_52; - case CudaArch::SM_53: - return CudaVirtualArch::COMPUTE_53; - case CudaArch::SM_60: - return CudaVirtualArch::COMPUTE_60; - case CudaArch::SM_61: - return CudaVirtualArch::COMPUTE_61; - case CudaArch::SM_62: - return CudaVirtualArch::COMPUTE_62; - case CudaArch::SM_70: - return CudaVirtualArch::COMPUTE_70; - case CudaArch::SM_72: - return CudaVirtualArch::COMPUTE_72; - case CudaArch::SM_75: - return CudaVirtualArch::COMPUTE_75; - case CudaArch::GFX600: - case CudaArch::GFX601: - case CudaArch::GFX700: - case CudaArch::GFX701: - case CudaArch::GFX702: - case CudaArch::GFX703: - case CudaArch::GFX704: - case CudaArch::GFX801: - case CudaArch::GFX802: - case CudaArch::GFX803: - case CudaArch::GFX810: - case CudaArch::GFX900: - case CudaArch::GFX902: - case CudaArch::GFX904: - case CudaArch::GFX906: - case CudaArch::GFX908: - case CudaArch::GFX909: - case CudaArch::GFX1010: - case CudaArch::GFX1011: - case CudaArch::GFX1012: - return CudaVirtualArch::COMPUTE_AMDGCN; - } - llvm_unreachable("invalid enum"); +CudaArch StringToCudaArch(llvm::StringRef S) { + auto result = std::find_if( + std::begin(arch_names), std::end(arch_names), + [S](const CudaArchToStringMap &map) { return S == map.arch_name; }); + if (result == std::end(arch_names)) + return CudaArch::UNKNOWN; + return result->arch; } CudaVersion MinVersionForCudaArch(CudaArch A) { - switch (A) { - case CudaArch::LAST: - break; - case CudaArch::UNKNOWN: + if (A == CudaArch::UNKNOWN) return CudaVersion::UNKNOWN; + + // AMD GPUs do not depend on CUDA versions. + if (IsAMDGpuArch(A)) + return CudaVersion::CUDA_70; + + switch (A) { case CudaArch::SM_20: case CudaArch::SM_21: case CudaArch::SM_30: @@ -307,60 +147,30 @@ CudaVersion MinVersionForCudaArch(CudaArch A) { return CudaVersion::CUDA_91; case CudaArch::SM_75: return CudaVersion::CUDA_100; - case CudaArch::GFX600: - case CudaArch::GFX601: - case CudaArch::GFX700: - case CudaArch::GFX701: - case CudaArch::GFX702: - case CudaArch::GFX703: - case CudaArch::GFX704: - case CudaArch::GFX801: - case CudaArch::GFX802: - case CudaArch::GFX803: - case CudaArch::GFX810: - case CudaArch::GFX900: - case CudaArch::GFX902: - case CudaArch::GFX904: - case CudaArch::GFX906: - case CudaArch::GFX908: - case CudaArch::GFX909: - case CudaArch::GFX1010: - case CudaArch::GFX1011: - case CudaArch::GFX1012: - return CudaVersion::CUDA_70; + case CudaArch::SM_80: + return CudaVersion::CUDA_110; + default: + llvm_unreachable("invalid enum"); } - llvm_unreachable("invalid enum"); } CudaVersion MaxVersionForCudaArch(CudaArch A) { + // AMD GPUs do not depend on CUDA versions. + if (IsAMDGpuArch(A)) + return CudaVersion::LATEST; + switch (A) { case CudaArch::UNKNOWN: return CudaVersion::UNKNOWN; case CudaArch::SM_20: case CudaArch::SM_21: - case CudaArch::GFX600: - case CudaArch::GFX601: - case CudaArch::GFX700: - case CudaArch::GFX701: - case CudaArch::GFX702: - case CudaArch::GFX703: - case CudaArch::GFX704: - case CudaArch::GFX801: - case CudaArch::GFX802: - case CudaArch::GFX803: - case CudaArch::GFX810: - case CudaArch::GFX900: - case CudaArch::GFX902: - case CudaArch::GFX1010: - case CudaArch::GFX1011: - case CudaArch::GFX1012: return CudaVersion::CUDA_80; default: return CudaVersion::LATEST; } } -static CudaVersion ToCudaVersion(llvm::VersionTuple Version) { +CudaVersion ToCudaVersion(llvm::VersionTuple Version) { int IVer = Version.getMajor() * 10 + Version.getMinor().getValueOr(0); switch(IVer) { @@ -380,6 +190,10 @@ static CudaVersion ToCudaVersion(llvm::VersionTuple Version) { return CudaVersion::CUDA_100; case 101: return CudaVersion::CUDA_101; + case 102: + return CudaVersion::CUDA_102; + case 110: + return CudaVersion::CUDA_110; default: return CudaVersion::UNKNOWN; } diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index f258b37f2fa6..661eabf9bc7c 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -61,6 +61,12 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, return DB; } +const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, + llvm::Error &&E) { + DB.AddString(toString(std::move(E))); + return DB; +} + static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT, StringRef Modifier, StringRef Argument, ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index e30e3753d193..8c7e63e06301 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -85,6 +85,7 @@ VALIDATE_DIAG_SIZE(LEX) VALIDATE_DIAG_SIZE(PARSE) VALIDATE_DIAG_SIZE(AST) VALIDATE_DIAG_SIZE(COMMENT) +VALIDATE_DIAG_SIZE(CROSSTU) VALIDATE_DIAG_SIZE(SEMA) VALIDATE_DIAG_SIZE(ANALYSIS) VALIDATE_DIAG_SIZE(REFACTORING) @@ -289,7 +290,7 @@ namespace clang { unsigned getOrCreateDiagID(DiagnosticIDs::Level L, StringRef Message, DiagnosticIDs &Diags) { - DiagDesc D(L, Message); + DiagDesc D(L, std::string(Message)); // Check to see if it already exists. std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D); if (I != DiagIDs.end() && I->first == D) diff --git a/clang/lib/Basic/ExpressionTraits.cpp b/clang/lib/Basic/ExpressionTraits.cpp new file mode 100644 index 000000000000..5fde1940038f --- /dev/null +++ b/clang/lib/Basic/ExpressionTraits.cpp @@ -0,0 +1,36 @@ +//===--- ExpressionTraits.cpp - Expression Traits Support -----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the expression traits support functions. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/ExpressionTraits.h" +#include "llvm/Support/ErrorHandling.h" +#include <cassert> +using namespace clang; + +static constexpr const char *ExpressionTraitNames[] = { +#define EXPRESSION_TRAIT(Spelling, Name, Key) #Name, +#include "clang/Basic/TokenKinds.def" +}; + +static constexpr const char *ExpressionTraitSpellings[] = { +#define EXPRESSION_TRAIT(Spelling, Name, Key) #Spelling, +#include "clang/Basic/TokenKinds.def" +}; + +const char *clang::getTraitName(ExpressionTrait T) { + assert(T <= ET_Last && "invalid enum value!"); + return ExpressionTraitNames[T]; +} + +const char *clang::getTraitSpelling(ExpressionTrait T) { + assert(T <= ET_Last && "invalid enum value!"); + return ExpressionTraitSpellings[T]; +} diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index 079a4bbfc82f..e92e9d5911c0 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -454,11 +454,12 @@ void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) { // misleading. We need to clean up the interface here. makeAbsolutePath(AbsPath); llvm::sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true); - UFE->RealPathName = AbsPath.str(); + UFE->RealPathName = std::string(AbsPath.str()); } llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> -FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile) { +FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile, + bool RequiresNullTerminator) { uint64_t FileSize = Entry->getSize(); // If there's a high enough chance that the file have changed since we // got its size, force a stat before opening it. @@ -468,28 +469,29 @@ FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile) { StringRef Filename = Entry->getName(); // If the file is already open, use the open file descriptor. if (Entry->File) { - auto Result = - Entry->File->getBuffer(Filename, FileSize, - /*RequiresNullTerminator=*/true, isVolatile); + auto Result = Entry->File->getBuffer(Filename, FileSize, + RequiresNullTerminator, isVolatile); Entry->closeFile(); return Result; } // Otherwise, open the file. - return getBufferForFileImpl(Filename, FileSize, isVolatile); + return getBufferForFileImpl(Filename, FileSize, isVolatile, + RequiresNullTerminator); } llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileManager::getBufferForFileImpl(StringRef Filename, int64_t FileSize, - bool isVolatile) { + bool isVolatile, + bool RequiresNullTerminator) { if (FileSystemOpts.WorkingDir.empty()) - return FS->getBufferForFile(Filename, FileSize, - /*RequiresNullTerminator=*/true, isVolatile); + return FS->getBufferForFile(Filename, FileSize, RequiresNullTerminator, + isVolatile); SmallString<128> FilePath(Filename); FixupRelativePath(FilePath); - return FS->getBufferForFile(FilePath, FileSize, - /*RequiresNullTerminator=*/true, isVolatile); + return FS->getBufferForFile(FilePath, FileSize, RequiresNullTerminator, + isVolatile); } /// getStatValue - Get the 'stat' information for the specified path, @@ -513,7 +515,7 @@ FileManager::getStatValue(StringRef Path, llvm::vfs::Status &Status, StatCache.get(), *FS); } -std::error_code +std::error_code FileManager::getNoncachedStatValue(StringRef Path, llvm::vfs::Status &Result) { SmallString<128> FilePath(Path); diff --git a/clang/lib/Basic/FixedPoint.cpp b/clang/lib/Basic/FixedPoint.cpp index 05600dfc6d21..ed8b92c98fdb 100644 --- a/clang/lib/Basic/FixedPoint.cpp +++ b/clang/lib/Basic/FixedPoint.cpp @@ -173,6 +173,142 @@ APFixedPoint APFixedPoint::add(const APFixedPoint &Other, return APFixedPoint(Result, CommonFXSema); } +APFixedPoint APFixedPoint::sub(const APFixedPoint &Other, + bool *Overflow) const { + auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics()); + APFixedPoint ConvertedThis = convert(CommonFXSema); + APFixedPoint ConvertedOther = Other.convert(CommonFXSema); + llvm::APSInt ThisVal = ConvertedThis.getValue(); + llvm::APSInt OtherVal = ConvertedOther.getValue(); + bool Overflowed = false; + + llvm::APSInt Result; + if (CommonFXSema.isSaturated()) { + Result = CommonFXSema.isSigned() ? ThisVal.ssub_sat(OtherVal) + : ThisVal.usub_sat(OtherVal); + } else { + Result = ThisVal.isSigned() ? ThisVal.ssub_ov(OtherVal, Overflowed) + : ThisVal.usub_ov(OtherVal, Overflowed); + } + + if (Overflow) + *Overflow = Overflowed; + + return APFixedPoint(Result, CommonFXSema); +} + +APFixedPoint APFixedPoint::mul(const APFixedPoint &Other, + bool *Overflow) const { + auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics()); + APFixedPoint ConvertedThis = convert(CommonFXSema); + APFixedPoint ConvertedOther = Other.convert(CommonFXSema); + llvm::APSInt ThisVal = ConvertedThis.getValue(); + llvm::APSInt OtherVal = ConvertedOther.getValue(); + bool Overflowed = false; + + // Widen the LHS and RHS so we can perform a full multiplication. + unsigned Wide = CommonFXSema.getWidth() * 2; + if (CommonFXSema.isSigned()) { + ThisVal = ThisVal.sextOrSelf(Wide); + OtherVal = OtherVal.sextOrSelf(Wide); + } else { + ThisVal = ThisVal.zextOrSelf(Wide); + OtherVal = OtherVal.zextOrSelf(Wide); + } + + // Perform the full multiplication and downscale to get the same scale. + // + // Note that the right shifts here perform an implicit downwards rounding. + // This rounding could discard bits that would technically place the result + // outside the representable range. We interpret the spec as allowing us to + // perform the rounding step first, avoiding the overflow case that would + // arise. + llvm::APSInt Result; + if (CommonFXSema.isSigned()) + Result = ThisVal.smul_ov(OtherVal, Overflowed) + .ashr(CommonFXSema.getScale()); + else + Result = ThisVal.umul_ov(OtherVal, Overflowed) + .lshr(CommonFXSema.getScale()); + assert(!Overflowed && "Full multiplication cannot overflow!"); + Result.setIsSigned(CommonFXSema.isSigned()); + + // If our result lies outside of the representative range of the common + // semantic, we either have overflow or saturation. + llvm::APSInt Max = APFixedPoint::getMax(CommonFXSema).getValue() + .extOrTrunc(Wide); + llvm::APSInt Min = APFixedPoint::getMin(CommonFXSema).getValue() + .extOrTrunc(Wide); + if (CommonFXSema.isSaturated()) { + if (Result < Min) + Result = Min; + else if (Result > Max) + Result = Max; + } else + Overflowed = Result < Min || Result > Max; + + if (Overflow) + *Overflow = Overflowed; + + return APFixedPoint(Result.sextOrTrunc(CommonFXSema.getWidth()), + CommonFXSema); +} + +APFixedPoint APFixedPoint::div(const APFixedPoint &Other, + bool *Overflow) const { + auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics()); + APFixedPoint ConvertedThis = convert(CommonFXSema); + APFixedPoint ConvertedOther = Other.convert(CommonFXSema); + llvm::APSInt ThisVal = ConvertedThis.getValue(); + llvm::APSInt OtherVal = ConvertedOther.getValue(); + bool Overflowed = false; + + // Widen the LHS and RHS so we can perform a full division. + unsigned Wide = CommonFXSema.getWidth() * 2; + if (CommonFXSema.isSigned()) { + ThisVal = ThisVal.sextOrSelf(Wide); + OtherVal = OtherVal.sextOrSelf(Wide); + } else { + ThisVal = ThisVal.zextOrSelf(Wide); + OtherVal = OtherVal.zextOrSelf(Wide); + } + + // Upscale to compensate for the loss of precision from division, and + // perform the full division. + ThisVal = ThisVal.shl(CommonFXSema.getScale()); + llvm::APSInt Result; + if (CommonFXSema.isSigned()) { + llvm::APInt Rem; + llvm::APInt::sdivrem(ThisVal, OtherVal, Result, Rem); + // If the quotient is negative and the remainder is nonzero, round + // towards negative infinity by subtracting epsilon from the result. + if (ThisVal.isNegative() != OtherVal.isNegative() && !Rem.isNullValue()) + Result = Result - 1; + } else + Result = ThisVal.udiv(OtherVal); + Result.setIsSigned(CommonFXSema.isSigned()); + + // If our result lies outside of the representative range of the common + // semantic, we either have overflow or saturation. + llvm::APSInt Max = APFixedPoint::getMax(CommonFXSema).getValue() + .extOrTrunc(Wide); + llvm::APSInt Min = APFixedPoint::getMin(CommonFXSema).getValue() + .extOrTrunc(Wide); + if (CommonFXSema.isSaturated()) { + if (Result < Min) + Result = Min; + else if (Result > Max) + Result = Max; + } else + Overflowed = Result < Min || Result > Max; + + if (Overflow) + *Overflow = Overflowed; + + return APFixedPoint(Result.sextOrTrunc(CommonFXSema.getWidth()), + CommonFXSema); +} + void APFixedPoint::toString(llvm::SmallVectorImpl<char> &Str) const { llvm::APSInt Val = getValue(); unsigned Scale = getScale(); diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp index 4aebea19924f..36b26d9b7c68 100644 --- a/clang/lib/Basic/IdentifierTable.cpp +++ b/clang/lib/Basic/IdentifierTable.cpp @@ -16,6 +16,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/Specifiers.h" +#include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TokenKinds.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/FoldingSet.h" @@ -32,6 +33,12 @@ using namespace clang; +// A check to make sure the ObjCOrBuiltinID has sufficient room to store the +// largest possible target/aux-target combination. If we exceed this, we likely +// need to just change the ObjCOrBuiltinIDBits value in IdentifierTable.h. +static_assert(2 * LargestBuiltinID < (2 << (ObjCOrBuiltinIDBits - 1)), + "Insufficient ObjCOrBuiltinID Bits"); + //===----------------------------------------------------------------------===// // IdentifierTable Implementation //===----------------------------------------------------------------------===// @@ -97,10 +104,10 @@ namespace { KEYZVECTOR = 0x40000, KEYCOROUTINES = 0x80000, KEYMODULES = 0x100000, - KEYCXX2A = 0x200000, + KEYCXX20 = 0x200000, KEYOPENCLCXX = 0x400000, KEYMSCOMPAT = 0x800000, - KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX2A, + KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX20, KEYALL = (0xffffff & ~KEYNOMS18 & ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude. }; @@ -122,7 +129,7 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts, if (Flags == KEYALL) return KS_Enabled; if (LangOpts.CPlusPlus && (Flags & KEYCXX)) return KS_Enabled; if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11)) return KS_Enabled; - if (LangOpts.CPlusPlus2a && (Flags & KEYCXX2A)) return KS_Enabled; + if (LangOpts.CPlusPlus20 && (Flags & KEYCXX20)) return KS_Enabled; if (LangOpts.C99 && (Flags & KEYC99)) return KS_Enabled; if (LangOpts.GNUKeywords && (Flags & KEYGNU)) return KS_Extension; if (LangOpts.MicrosoftExt && (Flags & KEYMS)) return KS_Extension; @@ -142,10 +149,12 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts, // We treat bridge casts as objective-C keywords so we can warn on them // in non-arc mode. if (LangOpts.ObjC && (Flags & KEYOBJC)) return KS_Enabled; - if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS)) return KS_Enabled; + if (LangOpts.CPlusPlus20 && (Flags & KEYCONCEPTS)) return KS_Enabled; if (LangOpts.Coroutines && (Flags & KEYCOROUTINES)) return KS_Enabled; if (LangOpts.ModulesTS && (Flags & KEYMODULES)) return KS_Enabled; if (LangOpts.CPlusPlus && (Flags & KEYALLCXX)) return KS_Future; + if (LangOpts.CPlusPlus && !LangOpts.CPlusPlus20 && (Flags & CHAR8SUPPORT)) + return KS_Future; return KS_Disabled; } @@ -257,7 +266,7 @@ bool IdentifierInfo::isCPlusPlusKeyword(const LangOptions &LangOpts) const { LangOptions LangOptsNoCPP = LangOpts; LangOptsNoCPP.CPlusPlus = false; LangOptsNoCPP.CPlusPlus11 = false; - LangOptsNoCPP.CPlusPlus2a = false; + LangOptsNoCPP.CPlusPlus20 = false; return !isKeyword(LangOptsNoCPP); } @@ -463,7 +472,7 @@ std::string MultiKeywordSelector::getName() const { OS << ':'; } - return OS.str(); + return std::string(OS.str()); } std::string Selector::getAsString() const { @@ -476,7 +485,7 @@ std::string Selector::getAsString() const { if (getNumArgs() == 0) { assert(II && "If the number of arguments is 0 then II is guaranteed to " "not be null."); - return II->getName(); + return std::string(II->getName()); } if (!II) diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp index 516b1ff1b7e2..c08670c87fb6 100644 --- a/clang/lib/Basic/LangOptions.cpp +++ b/clang/lib/Basic/LangOptions.cpp @@ -24,7 +24,7 @@ void LangOptions::resetNonModularOptions() { #define LANGOPT(Name, Bits, Default, Description) #define BENIGN_LANGOPT(Name, Bits, Default, Description) Name = Default; #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ - Name = Default; + Name = static_cast<unsigned>(Default); #include "clang/Basic/LangOptions.def" // These options do not affect AST generation. @@ -47,3 +47,23 @@ VersionTuple LangOptions::getOpenCLVersionTuple() const { const int Ver = OpenCLCPlusPlus ? OpenCLCPlusPlusVersion : OpenCLVersion; return VersionTuple(Ver / 100, (Ver % 100) / 10); } + +FPOptions FPOptions::defaultWithoutTrailingStorage(const LangOptions &LO) { + FPOptions result(LO); + return result; +} + +LLVM_DUMP_METHOD void FPOptions::dump() { +#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ + llvm::errs() << "\n " #NAME " " << get##NAME(); +#include "clang/Basic/FPOptions.def" + llvm::errs() << "\n"; +} + +LLVM_DUMP_METHOD void FPOptionsOverride::dump() { +#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ + if (has##NAME##Override()) \ + llvm::errs() << "\n " #NAME " Override is " << get##NAME##Override(); +#include "clang/Basic/FPOptions.def" + llvm::errs() << "\n"; +} diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp index 541431dbbe7d..b3daaa3a4442 100644 --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -37,26 +37,21 @@ using namespace clang; Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, bool IsFramework, bool IsExplicit, unsigned VisibilityID) : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), - VisibilityID(VisibilityID), IsMissingRequirement(false), + VisibilityID(VisibilityID), IsUnimportable(false), HasIncompatibleModuleFile(false), IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), IsExternC(false), IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false), InferExportWildcard(false), ConfigMacrosExhaustive(false), NoUndeclaredIncludes(false), ModuleMapIsPrivate(false), - NameVisibility(Hidden) { + HasUmbrellaDir(false), NameVisibility(Hidden) { if (Parent) { - if (!Parent->isAvailable()) - IsAvailable = false; - if (Parent->IsSystem) - IsSystem = true; - if (Parent->IsExternC) - IsExternC = true; - if (Parent->NoUndeclaredIncludes) - NoUndeclaredIncludes = true; - if (Parent->ModuleMapIsPrivate) - ModuleMapIsPrivate = true; - IsMissingRequirement = Parent->IsMissingRequirement; + IsAvailable = Parent->isAvailable(); + IsUnimportable = Parent->isUnimportable(); + IsSystem = Parent->IsSystem; + IsExternC = Parent->IsExternC; + NoUndeclaredIncludes = Parent->NoUndeclaredIncludes; + ModuleMapIsPrivate = Parent->ModuleMapIsPrivate; Parent->SubModuleIndex[Name] = Parent->SubModules.size(); Parent->SubModules.push_back(this); @@ -132,25 +127,42 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, return HasFeature; } -bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, - Requirement &Req, - UnresolvedHeaderDirective &MissingHeader, - Module *&ShadowingModule) const { - if (IsAvailable) - return true; +bool Module::isUnimportable(const LangOptions &LangOpts, + const TargetInfo &Target, Requirement &Req, + Module *&ShadowingModule) const { + if (!IsUnimportable) + return false; for (const Module *Current = this; Current; Current = Current->Parent) { if (Current->ShadowingModule) { ShadowingModule = Current->ShadowingModule; - return false; + return true; } for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != Current->Requirements[I].second) { Req = Current->Requirements[I]; - return false; + return true; } } + } + + llvm_unreachable("could not find a reason why module is unimportable"); +} + +bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, + Requirement &Req, + UnresolvedHeaderDirective &MissingHeader, + Module *&ShadowingModule) const { + if (IsAvailable) + return true; + + if (isUnimportable(LangOpts, Target, Req, ShadowingModule)) + return false; + + // FIXME: All missing headers are listed on the top-level module. Should we + // just look there? + for (const Module *Current = this; Current; Current = Current->Parent) { if (!Current->MissingHeaders.empty()) { MissingHeader = Current->MissingHeaders.front(); return false; @@ -239,7 +251,12 @@ Module::DirectoryName Module::getUmbrellaDir() const { if (Header U = getUmbrellaHeader()) return {"", U.Entry->getDir()}; - return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; + return {UmbrellaAsWritten, static_cast<const DirectoryEntry *>(Umbrella)}; +} + +void Module::addTopHeader(const FileEntry *File) { + assert(File); + TopHeaders.insert(File); } ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { @@ -276,18 +293,18 @@ bool Module::directlyUses(const Module *Requested) const { void Module::addRequirement(StringRef Feature, bool RequiredState, const LangOptions &LangOpts, const TargetInfo &Target) { - Requirements.push_back(Requirement(Feature, RequiredState)); + Requirements.push_back(Requirement(std::string(Feature), RequiredState)); // If this feature is currently available, we're done. if (hasFeature(Feature, LangOpts, Target) == RequiredState) return; - markUnavailable(/*MissingRequirement*/true); + markUnavailable(/*Unimportable*/true); } -void Module::markUnavailable(bool MissingRequirement) { - auto needUpdate = [MissingRequirement](Module *M) { - return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement); +void Module::markUnavailable(bool Unimportable) { + auto needUpdate = [Unimportable](Module *M) { + return M->IsAvailable || (!M->IsUnimportable && Unimportable); }; if (!needUpdate(this)) @@ -303,7 +320,7 @@ void Module::markUnavailable(bool MissingRequirement) { continue; Current->IsAvailable = false; - Current->IsMissingRequirement |= MissingRequirement; + Current->IsUnimportable |= Unimportable; for (submodule_iterator Sub = Current->submodule_begin(), SubEnd = Current->submodule_end(); Sub != SubEnd; ++Sub) { @@ -637,8 +654,8 @@ void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, SmallVector<Module *, 16> Exports; V.M->getExportedModules(Exports); for (Module *E : Exports) { - // Don't recurse to unavailable submodules. - if (E->isAvailable()) + // Don't import non-importable modules. + if (!E->isUnimportable()) VisitModule({E, &V}); } @@ -653,3 +670,18 @@ void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, }; VisitModule({M, nullptr}); } + +ASTSourceDescriptor::ASTSourceDescriptor(Module &M) + : Signature(M.Signature), ClangModule(&M) { + if (M.Directory) + Path = M.Directory->getName(); + if (auto *File = M.getASTFile()) + ASTFile = File->getName(); +} + +std::string ASTSourceDescriptor::getModuleName() const { + if (ClangModule) + return ClangModule->Name; + else + return std::string(PCHModuleName); +} diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 414ebb52c0c7..cae61ad4f2e3 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -20,94 +20,14 @@ using namespace clang; using namespace llvm::omp; -OpenMPContextSelectorSetKind -clang::getOpenMPContextSelectorSet(llvm::StringRef Str) { - return llvm::StringSwitch<OpenMPContextSelectorSetKind>(Str) -#define OPENMP_CONTEXT_SELECTOR_SET(Name) .Case(#Name, OMP_CTX_SET_##Name) -#include "clang/Basic/OpenMPKinds.def" - .Default(OMP_CTX_SET_unknown); -} - -llvm::StringRef -clang::getOpenMPContextSelectorSetName(OpenMPContextSelectorSetKind Kind) { - switch (Kind) { - case OMP_CTX_SET_unknown: - return "unknown"; -#define OPENMP_CONTEXT_SELECTOR_SET(Name) \ - case OMP_CTX_SET_##Name: \ - return #Name; -#include "clang/Basic/OpenMPKinds.def" - break; - } - llvm_unreachable("Invalid OpenMP context selector set kind"); -} - -OpenMPContextSelectorKind clang::getOpenMPContextSelector(llvm::StringRef Str) { - return llvm::StringSwitch<OpenMPContextSelectorKind>(Str) -#define OPENMP_CONTEXT_SELECTOR(Name) .Case(#Name, OMP_CTX_##Name) -#include "clang/Basic/OpenMPKinds.def" - .Default(OMP_CTX_unknown); -} - -llvm::StringRef -clang::getOpenMPContextSelectorName(OpenMPContextSelectorKind Kind) { - switch (Kind) { - case OMP_CTX_unknown: - return "unknown"; -#define OPENMP_CONTEXT_SELECTOR(Name) \ - case OMP_CTX_##Name: \ - return #Name; -#include "clang/Basic/OpenMPKinds.def" - break; - } - llvm_unreachable("Invalid OpenMP context selector kind"); -} - -OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) { - // 'flush' clause cannot be specified explicitly, because this is an implicit - // clause for 'flush' directive. If the 'flush' clause is explicitly specified - // the Parser should generate a warning about extra tokens at the end of the - // directive. - if (Str == "flush") - return OMPC_unknown; - return llvm::StringSwitch<OpenMPClauseKind>(Str) -#define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name) -#include "clang/Basic/OpenMPKinds.def" - .Case("uniform", OMPC_uniform) - .Case("device_type", OMPC_device_type) - .Case("match", OMPC_match) - .Default(OMPC_unknown); -} - -const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) { - assert(Kind <= OMPC_unknown); - switch (Kind) { - case OMPC_unknown: - return "unknown"; -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ - return #Name; -#include "clang/Basic/OpenMPKinds.def" - case OMPC_uniform: - return "uniform"; - case OMPC_threadprivate: - return "threadprivate or thread local"; - case OMPC_device_type: - return "device_type"; - case OMPC_match: - return "match"; - } - llvm_unreachable("Invalid OpenMP clause kind"); -} - unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str) { switch (Kind) { case OMPC_default: - return llvm::StringSwitch<OpenMPDefaultClauseKind>(Str) -#define OPENMP_DEFAULT_KIND(Name) .Case(#Name, OMPC_DEFAULT_##Name) -#include "clang/Basic/OpenMPKinds.def" - .Default(OMPC_DEFAULT_unknown); + return llvm::StringSwitch<unsigned>(Str) +#define OMP_DEFAULT_KIND(Enum, Name) .Case(Name, unsigned(Enum)) +#include "llvm/Frontend/OpenMP/OMPKinds.def" + .Default(unsigned(llvm::omp::OMP_DEFAULT_unknown)); case OMPC_proc_bind: return llvm::StringSwitch<unsigned>(Str) #define OMP_PROC_BIND_KIND(Enum, Name, Value) .Case(Name, Value) @@ -180,6 +100,26 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, #define OPENMP_LASTPRIVATE_KIND(Name) .Case(#Name, OMPC_LASTPRIVATE_##Name) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_LASTPRIVATE_unknown); + case OMPC_order: + return llvm::StringSwitch<OpenMPOrderClauseKind>(Str) +#define OPENMP_ORDER_KIND(Name) .Case(#Name, OMPC_ORDER_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_ORDER_unknown); + case OMPC_update: + return llvm::StringSwitch<OpenMPDependClauseKind>(Str) +#define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_DEPEND_unknown); + case OMPC_device: + return llvm::StringSwitch<OpenMPDeviceClauseModifier>(Str) +#define OPENMP_DEVICE_MODIFIER(Name) .Case(#Name, OMPC_DEVICE_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_DEVICE_unknown); + case OMPC_reduction: + return llvm::StringSwitch<OpenMPReductionClauseModifier>(Str) +#define OPENMP_REDUCTION_MODIFIER(Name) .Case(#Name, OMPC_REDUCTION_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_REDUCTION_unknown); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -193,7 +133,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_private: case OMPC_firstprivate: case OMPC_shared: - case OMPC_reduction: case OMPC_task_reduction: case OMPC_in_reduction: case OMPC_aligned: @@ -204,12 +143,15 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_untied: case OMPC_mergeable: case OMPC_flush: + case OMPC_depobj: case OMPC_read: case OMPC_write: - case OMPC_update: case OMPC_capture: case OMPC_seq_cst: - case OMPC_device: + case OMPC_acq_rel: + case OMPC_acquire: + case OMPC_release: + case OMPC_relaxed: case OMPC_threads: case OMPC_simd: case OMPC_num_teams: @@ -221,6 +163,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_hint: case OMPC_uniform: case OMPC_use_device_ptr: + case OMPC_use_device_addr: case OMPC_is_device_ptr: case OMPC_unified_address: case OMPC_unified_shared_memory: @@ -228,6 +171,14 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_dynamic_allocators: case OMPC_match: case OMPC_nontemporal: + case OMPC_destroy: + case OMPC_detach: + case OMPC_inclusive: + case OMPC_exclusive: + case OMPC_uses_allocators: + case OMPC_affinity: + break; + default: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); @@ -237,13 +188,11 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type) { switch (Kind) { case OMPC_default: - switch (Type) { - case OMPC_DEFAULT_unknown: - return "unknown"; -#define OPENMP_DEFAULT_KIND(Name) \ - case OMPC_DEFAULT_##Name: \ - return #Name; -#include "clang/Basic/OpenMPKinds.def" + switch (llvm::omp::DefaultKind(Type)) { +#define OMP_DEFAULT_KIND(Enum, Name) \ + case Enum: \ + return Name; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } llvm_unreachable("Invalid OpenMP 'default' clause type"); case OMPC_proc_bind: @@ -382,6 +331,46 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'lastprivate' clause type"); + case OMPC_order: + switch (Type) { + case OMPC_ORDER_unknown: + return "unknown"; +#define OPENMP_ORDER_KIND(Name) \ + case OMPC_ORDER_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'order' clause type"); + case OMPC_update: + switch (Type) { + case OMPC_DEPEND_unknown: + return "unknown"; +#define OPENMP_DEPEND_KIND(Name) \ + case OMPC_DEPEND_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'depend' clause type"); + case OMPC_device: + switch (Type) { + case OMPC_DEVICE_unknown: + return "unknown"; +#define OPENMP_DEVICE_MODIFIER(Name) \ + case OMPC_DEVICE_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'device' clause modifier"); + case OMPC_reduction: + switch (Type) { + case OMPC_REDUCTION_unknown: + return "unknown"; +#define OPENMP_REDUCTION_MODIFIER(Name) \ + case OMPC_REDUCTION_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'reduction' clause modifier"); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -395,7 +384,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_private: case OMPC_firstprivate: case OMPC_shared: - case OMPC_reduction: case OMPC_task_reduction: case OMPC_in_reduction: case OMPC_aligned: @@ -406,12 +394,15 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_untied: case OMPC_mergeable: case OMPC_flush: + case OMPC_depobj: case OMPC_read: case OMPC_write: - case OMPC_update: case OMPC_capture: case OMPC_seq_cst: - case OMPC_device: + case OMPC_acq_rel: + case OMPC_acquire: + case OMPC_release: + case OMPC_relaxed: case OMPC_threads: case OMPC_simd: case OMPC_num_teams: @@ -423,6 +414,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_hint: case OMPC_uniform: case OMPC_use_device_ptr: + case OMPC_use_device_addr: case OMPC_is_device_ptr: case OMPC_unified_address: case OMPC_unified_shared_memory: @@ -430,536 +422,17 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_dynamic_allocators: case OMPC_match: case OMPC_nontemporal: + case OMPC_destroy: + case OMPC_detach: + case OMPC_inclusive: + case OMPC_exclusive: + case OMPC_uses_allocators: + case OMPC_affinity: break; - } - llvm_unreachable("Invalid OpenMP simple clause kind"); -} - -bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, - OpenMPClauseKind CKind, - unsigned OpenMPVersion) { - assert(unsigned(DKind) <= unsigned(OMPD_unknown)); - assert(CKind <= OMPC_unknown); - // Nontemporal clause is not supported in OpenMP < 5.0. - if (OpenMPVersion < 50 && CKind == OMPC_nontemporal) - return false; - switch (DKind) { - case OMPD_parallel: - switch (CKind) { -#define OPENMP_PARALLEL_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_simd: - if (OpenMPVersion < 50 && CKind == OMPC_if) - return false; - switch (CKind) { -#define OPENMP_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_for: - switch (CKind) { -#define OPENMP_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_for_simd: - if (OpenMPVersion < 50 && CKind == OMPC_if) - return false; - switch (CKind) { -#define OPENMP_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_sections: - switch (CKind) { -#define OPENMP_SECTIONS_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_single: - switch (CKind) { -#define OPENMP_SINGLE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_for: - switch (CKind) { -#define OPENMP_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_for_simd: - switch (CKind) { -#define OPENMP_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_master: - switch (CKind) { -#define OPENMP_PARALLEL_MASTER_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_sections: - switch (CKind) { -#define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_task: - switch (CKind) { -#define OPENMP_TASK_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_flush: - return CKind == OMPC_flush; - break; - case OMPD_atomic: - switch (CKind) { -#define OPENMP_ATOMIC_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target: - switch (CKind) { -#define OPENMP_TARGET_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_requires: - switch (CKind) { -#define OPENMP_REQUIRES_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_data: - switch (CKind) { -#define OPENMP_TARGET_DATA_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_enter_data: - switch (CKind) { -#define OPENMP_TARGET_ENTER_DATA_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_exit_data: - switch (CKind) { -#define OPENMP_TARGET_EXIT_DATA_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_parallel: - switch (CKind) { -#define OPENMP_TARGET_PARALLEL_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_parallel_for: - switch (CKind) { -#define OPENMP_TARGET_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_update: - switch (CKind) { -#define OPENMP_TARGET_UPDATE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams: - switch (CKind) { -#define OPENMP_TEAMS_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_cancel: - switch (CKind) { -#define OPENMP_CANCEL_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_ordered: - switch (CKind) { -#define OPENMP_ORDERED_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_taskloop: - switch (CKind) { -#define OPENMP_TASKLOOP_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_taskloop_simd: - switch (CKind) { -#define OPENMP_TASKLOOP_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_master_taskloop: - switch (CKind) { -#define OPENMP_MASTER_TASKLOOP_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_master_taskloop_simd: - switch (CKind) { -#define OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_master_taskloop: - switch (CKind) { -#define OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_master_taskloop_simd: - switch (CKind) { -#define OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_critical: - switch (CKind) { -#define OPENMP_CRITICAL_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_distribute: - switch (CKind) { -#define OPENMP_DISTRIBUTE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_distribute_parallel_for: - switch (CKind) { -#define OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_distribute_parallel_for_simd: - switch (CKind) { -#define OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_distribute_simd: - if (OpenMPVersion < 50 && CKind == OMPC_if) - return false; - switch (CKind) { -#define OPENMP_DISTRIBUTE_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_parallel_for_simd: - switch (CKind) { -#define OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_simd: - switch (CKind) { -#define OPENMP_TARGET_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams_distribute: - switch (CKind) { -#define OPENMP_TEAMS_DISTRIBUTE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams_distribute_simd: - if (OpenMPVersion < 50 && CKind == OMPC_if) - return false; - switch (CKind) { -#define OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams_distribute_parallel_for_simd: - switch (CKind) { -#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams_distribute_parallel_for: - switch (CKind) { -#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams_distribute: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams_distribute_parallel_for: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams_distribute_parallel_for_simd: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams_distribute_simd: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_taskgroup: - switch (CKind) { -#define OPENMP_TASKGROUP_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_declare_mapper: - switch (CKind) { -#define OPENMP_DECLARE_MAPPER_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_allocate: - switch (CKind) { -#define OPENMP_ALLOCATE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_declare_variant: - switch (CKind) { -#define OPENMP_DECLARE_VARIANT_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_unknown: - case OMPD_threadprivate: - case OMPD_section: - case OMPD_master: - case OMPD_taskyield: - case OMPD_barrier: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_declare_reduction: - case OMPD_declare_simd: + default: break; } - return false; + llvm_unreachable("Invalid OpenMP simple clause kind"); } bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { @@ -1111,7 +584,7 @@ bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) { void clang::getOpenMPCaptureRegions( SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions, OpenMPDirectiveKind DKind) { - assert(DKind <= OMPD_unknown); + assert(unsigned(DKind) < llvm::omp::Directive_enumSize); switch (DKind) { case OMPD_parallel: case OMPD_parallel_for: @@ -1199,6 +672,8 @@ void clang::getOpenMPCaptureRegions( case OMPD_cancellation_point: case OMPD_cancel: case OMPD_flush: + case OMPD_depobj: + case OMPD_scan: case OMPD_declare_reduction: case OMPD_declare_mapper: case OMPD_declare_simd: @@ -1206,8 +681,11 @@ void clang::getOpenMPCaptureRegions( case OMPD_end_declare_target: case OMPD_requires: case OMPD_declare_variant: + case OMPD_begin_declare_variant: + case OMPD_end_declare_variant: llvm_unreachable("OpenMP Directive is not allowed"); case OMPD_unknown: + default: llvm_unreachable("Unknown OpenMP directive"); } } diff --git a/clang/lib/Basic/SanitizerBlacklist.cpp b/clang/lib/Basic/SanitizerBlacklist.cpp index 4f71349350fd..feb7cbda39b7 100644 --- a/clang/lib/Basic/SanitizerBlacklist.cpp +++ b/clang/lib/Basic/SanitizerBlacklist.cpp @@ -10,7 +10,12 @@ // sanitizers. // //===----------------------------------------------------------------------===// + #include "clang/Basic/SanitizerBlacklist.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/SanitizerSpecialCaseList.h" +#include "clang/Basic/Sanitizers.h" +#include "clang/Basic/SourceManager.h" using namespace clang; @@ -20,6 +25,8 @@ SanitizerBlacklist::SanitizerBlacklist( BlacklistPaths, SM.getFileManager().getVirtualFileSystem())), SM(SM) {} +SanitizerBlacklist::~SanitizerBlacklist() = default; + bool SanitizerBlacklist::isBlacklistedGlobal(SanitizerMask Mask, StringRef GlobalName, StringRef Category) const { diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index 73f2ae96d4a3..0a76c78cd44f 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -17,12 +17,12 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManagerInternals.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Capacity.h" #include "llvm/Support/Compiler.h" @@ -389,6 +389,14 @@ void SourceManager::clearIDTables() { createExpansionLoc(SourceLocation(), SourceLocation(), SourceLocation(), 1); } +bool SourceManager::isMainFile(FileEntryRef SourceFile) { + assert(MainFileID.isValid() && "expected initialized SourceManager"); + auto FE = getFileEntryRefForID(MainFileID); + if (!FE) + return false; + return FE->getUID() == SourceFile.getUID(); +} + void SourceManager::initializeForReplay(const SourceManager &Old) { assert(MainFileID.isInvalid() && "expected uninitialized SourceManager"); @@ -560,6 +568,70 @@ FileID SourceManager::getNextFileID(FileID FID) const { // Methods to create new FileID's and macro expansions. //===----------------------------------------------------------------------===// +/// Create a new FileID that represents the specified file +/// being \#included from the specified IncludePosition. +/// +/// This translates NULL into standard input. +FileID SourceManager::createFileID(const FileEntry *SourceFile, + SourceLocation IncludePos, + SrcMgr::CharacteristicKind FileCharacter, + int LoadedID, unsigned LoadedOffset) { + assert(SourceFile && "Null source file!"); + const SrcMgr::ContentCache *IR = + getOrCreateContentCache(SourceFile, isSystem(FileCharacter)); + assert(IR && "getOrCreateContentCache() cannot return NULL"); + return createFileID(IR, SourceFile->getName(), IncludePos, FileCharacter, + LoadedID, LoadedOffset); +} + +FileID SourceManager::createFileID(FileEntryRef SourceFile, + SourceLocation IncludePos, + SrcMgr::CharacteristicKind FileCharacter, + int LoadedID, unsigned LoadedOffset) { + const SrcMgr::ContentCache *IR = getOrCreateContentCache( + &SourceFile.getFileEntry(), isSystem(FileCharacter)); + assert(IR && "getOrCreateContentCache() cannot return NULL"); + return createFileID(IR, SourceFile.getName(), IncludePos, FileCharacter, + LoadedID, LoadedOffset); +} + +/// Create a new FileID that represents the specified memory buffer. +/// +/// This does no caching of the buffer and takes ownership of the +/// MemoryBuffer, so only pass a MemoryBuffer to this once. +FileID SourceManager::createFileID(std::unique_ptr<llvm::MemoryBuffer> Buffer, + SrcMgr::CharacteristicKind FileCharacter, + int LoadedID, unsigned LoadedOffset, + SourceLocation IncludeLoc) { + StringRef Name = Buffer->getBufferIdentifier(); + return createFileID( + createMemBufferContentCache(Buffer.release(), /*DoNotFree*/ false), + Name, IncludeLoc, FileCharacter, LoadedID, LoadedOffset); +} + +/// Create a new FileID that represents the specified memory buffer. +/// +/// This does not take ownership of the MemoryBuffer. The memory buffer must +/// outlive the SourceManager. +FileID SourceManager::createFileID(UnownedTag, const llvm::MemoryBuffer *Buffer, + SrcMgr::CharacteristicKind FileCharacter, + int LoadedID, unsigned LoadedOffset, + SourceLocation IncludeLoc) { + return createFileID(createMemBufferContentCache(Buffer, /*DoNotFree*/ true), + Buffer->getBufferIdentifier(), IncludeLoc, + FileCharacter, LoadedID, LoadedOffset); +} + +/// Get the FileID for \p SourceFile if it exists. Otherwise, create a +/// new FileID for the \p SourceFile. +FileID +SourceManager::getOrCreateFileID(const FileEntry *SourceFile, + SrcMgr::CharacteristicKind FileCharacter) { + FileID ID = translateFile(SourceFile); + return ID.isValid() ? ID : createFileID(SourceFile, SourceLocation(), + FileCharacter); +} + /// createFileID - Create a new FileID for the specified ContentCache and /// include position. This works regardless of whether the ContentCache /// corresponds to a file or some other input source. @@ -577,13 +649,15 @@ FileID SourceManager::createFileID(const ContentCache *File, StringRef Filename, SLocEntryLoaded[Index] = true; return FileID::get(LoadedID); } + unsigned FileSize = File->getSize(); + if (!(NextLocalOffset + FileSize + 1 > NextLocalOffset && + NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset)) { + Diag.Report(IncludePos, diag::err_include_too_large); + return FileID(); + } LocalSLocEntryTable.push_back( SLocEntry::get(NextLocalOffset, FileInfo::get(IncludePos, File, FileCharacter, Filename))); - unsigned FileSize = File->getSize(); - assert(NextLocalOffset + FileSize + 1 > NextLocalOffset && - NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset && - "Ran out of source locations!"); // We do a +1 here because we want a SourceLocation that means "the end of the // file", e.g. for the "no newline at the end of the file" diagnostic. NextLocalOffset += FileSize + 1; @@ -699,6 +773,18 @@ void SourceManager::setFileIsTransient(const FileEntry *File) { const_cast<SrcMgr::ContentCache *>(CC)->IsTransient = true; } +Optional<FileEntryRef> SourceManager::getFileEntryRefForID(FileID FID) const { + bool Invalid = false; + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); + if (Invalid || !Entry.isFile()) + return None; + + const SrcMgr::ContentCache *Content = Entry.getFile().getContentCache(); + if (!Content || !Content->OrigEntry) + return None; + return FileEntryRef(Entry.getFile().getName(), *Content->OrigEntry); +} + StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const { bool MyInvalid = false; const SLocEntry &SLoc = getSLocEntry(FID, &MyInvalid); @@ -775,11 +861,8 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { --I; if (I->getOffset() <= SLocOffset) { FileID Res = FileID::get(int(I - LocalSLocEntryTable.begin())); - - // If this isn't an expansion, remember it. We have good locality across - // FileID lookups. - if (!I->isExpansion()) - LastFileIDLookup = Res; + // Remember it. We have good locality across FileID lookups. + LastFileIDLookup = Res; NumLinearScans += NumProbes+1; return Res; } @@ -796,11 +879,8 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { unsigned LessIndex = 0; NumProbes = 0; while (true) { - bool Invalid = false; unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex; - unsigned MidOffset = getLocalSLocEntry(MiddleIndex, &Invalid).getOffset(); - if (Invalid) - return FileID::get(0); + unsigned MidOffset = getLocalSLocEntry(MiddleIndex).getOffset(); ++NumProbes; @@ -812,15 +892,12 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { } // If the middle index contains the value, succeed and return. - // FIXME: This could be made faster by using a function that's aware of - // being in the local area. - if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) { + if (MiddleIndex + 1 == LocalSLocEntryTable.size() || + SLocOffset < getLocalSLocEntry(MiddleIndex + 1).getOffset()) { FileID Res = FileID::get(MiddleIndex); - // If this isn't a macro expansion, remember it. We have good locality - // across FileID lookups. - if (!LocalSLocEntryTable[MiddleIndex].isExpansion()) - LastFileIDLookup = Res; + // Remember it. We have good locality across FileID lookups. + LastFileIDLookup = Res; NumBinaryProbes += NumProbes; return Res; } @@ -858,9 +935,7 @@ FileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const { const SrcMgr::SLocEntry &E = getLoadedSLocEntry(I); if (E.getOffset() <= SLocOffset) { FileID Res = FileID::get(-int(I) - 2); - - if (!E.isExpansion()) - LastFileIDLookup = Res; + LastFileIDLookup = Res; NumLinearScans += NumProbes + 1; return Res; } @@ -893,8 +968,7 @@ FileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const { if (isOffsetInFileID(FileID::get(-int(MiddleIndex) - 2), SLocOffset)) { FileID Res = FileID::get(-int(MiddleIndex) - 2); - if (!E.isExpansion()) - LastFileIDLookup = Res; + LastFileIDLookup = Res; NumBinaryProbes += NumProbes; return Res; } @@ -990,6 +1064,13 @@ SourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{ return Loc.getLocWithOffset(LocInfo.second); } +/// Return the filename of the file containing a SourceLocation. +StringRef SourceManager::getFilename(SourceLocation SpellingLoc) const { + if (const FileEntry *F = getFileEntryForID(getFileID(SpellingLoc))) + return F->getName(); + return StringRef(); +} + /// getImmediateExpansionRange - Loc is required to be an expansion location. /// Return the start/end of the expansion information. CharSourceRange @@ -1602,11 +1683,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { // The location we're looking for isn't in the main file; look // through all of the local source locations. for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) { - bool Invalid = false; - const SLocEntry &SLoc = getLocalSLocEntry(I, &Invalid); - if (Invalid) - return FileID(); - + const SLocEntry &SLoc = getLocalSLocEntry(I); if (SLoc.isFile() && SLoc.getFile().getContentCache() && SLoc.getFile().getContentCache()->OrigEntry == SourceFile) return FileID::get(I); @@ -1715,15 +1792,23 @@ void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache, return; if (Entry.isFile()) { SourceLocation IncludeLoc = Entry.getFile().getIncludeLoc(); - if (IncludeLoc.isInvalid()) + bool IncludedInFID = + (IncludeLoc.isValid() && isInFileID(IncludeLoc, FID)) || + // Predefined header doesn't have a valid include location in main + // file, but any files created by it should still be skipped when + // computing macro args expanded in the main file. + (FID == MainFileID && Entry.getFile().Filename == "<built-in>"); + if (IncludedInFID) { + // Skip the files/macros of the #include'd file, we only care about + // macros that lexed macro arguments from our file. + if (Entry.getFile().NumCreatedFIDs) + ID += Entry.getFile().NumCreatedFIDs - 1 /*because of next ++ID*/; continue; - if (!isInFileID(IncludeLoc, FID)) - return; // No more files/macros that may be "contained" in this file. - - // Skip the files/macros of the #include'd file, we only care about macros - // that lexed macro arguments from our file. - if (Entry.getFile().NumCreatedFIDs) - ID += Entry.getFile().NumCreatedFIDs - 1/*because of next ++ID*/; + } else if (IncludeLoc.isValid()) { + // If file was included but not from FID, there is no more files/macros + // that may be "contained" in this file. + return; + } continue; } diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 3a21a19e1f19..eccdc21d724a 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -36,6 +36,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { HasLegalHalfType = false; HasFloat128 = false; HasFloat16 = false; + HasBFloat16 = false; + HasStrictFP = false; PointerWidth = PointerAlign = 32; BoolWidth = BoolAlign = 8; IntWidth = IntAlign = 32; @@ -113,6 +115,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { HasBuiltinMSVaList = false; IsRenderScriptTarget = false; HasAArch64SVETypes = false; + ARMCDECoprocMask = 0; // Default to no types using fpret. RealTypeUsesObjCFPRet = 0; @@ -132,6 +135,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { // Default to an unknown platform name. PlatformName = "unknown"; PlatformMinVersion = VersionTuple(); + + MaxOpenCLWorkGroupSize = 1024; } // Out of line virtual dtor for TargetInfo. @@ -262,7 +267,8 @@ TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth, return NoInt; } -TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const { +TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth, + bool ExplicitIEEE) const { if (getFloatWidth() == BitWidth) return Float; if (getDoubleWidth() == BitWidth) @@ -274,6 +280,10 @@ TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const { return LongDouble; break; case 128: + // The caller explicitly asked for an IEEE compliant type but we still + // have to check if the target supports it. + if (ExplicitIEEE) + return hasFloat128Type() ? Float128 : NoFloat; if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() || &getLongDoubleFormat() == &llvm::APFloat::IEEEquad()) return LongDouble; @@ -379,6 +389,20 @@ void TargetInfo::adjust(LangOptions &Opts) { LongDoubleFormat = &llvm::APFloat::IEEEquad(); } + if (Opts.DoubleSize) { + if (Opts.DoubleSize == 32) { + DoubleWidth = 32; + LongDoubleWidth = 32; + DoubleFormat = &llvm::APFloat::IEEEsingle(); + LongDoubleFormat = &llvm::APFloat::IEEEsingle(); + } else if (Opts.DoubleSize == 64) { + DoubleWidth = 64; + LongDoubleWidth = 64; + DoubleFormat = &llvm::APFloat::IEEEdouble(); + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } + } + if (Opts.LongDoubleSize) { if (Opts.LongDoubleSize == DoubleWidth) { LongDoubleWidth = DoubleWidth; diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index c063f8ca4472..6bbcafa27dfe 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -33,6 +33,7 @@ #include "Targets/Sparc.h" #include "Targets/SystemZ.h" #include "Targets/TCE.h" +#include "Targets/VE.h" #include "Targets/WebAssembly.h" #include "Targets/X86.h" #include "Targets/XCore.h" @@ -117,6 +118,9 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new XCoreTargetInfo(Triple, Opts); case llvm::Triple::hexagon: + if (os == llvm::Triple::Linux && + Triple.getEnvironment() == llvm::Triple::Musl) + return new LinuxTargetInfo<HexagonTargetInfo>(Triple, Opts); return new HexagonTargetInfo(Triple, Opts); case llvm::Triple::lanai: @@ -477,6 +481,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new OpenBSDI386TargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::KFreeBSD: return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::Minix: @@ -608,6 +614,9 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new LinuxTargetInfo<RenderScript32TargetInfo>(Triple, Opts); case llvm::Triple::renderscript64: return new LinuxTargetInfo<RenderScript64TargetInfo>(Triple, Opts); + + case llvm::Triple::ve: + return new LinuxTargetInfo<VETargetInfo>(Triple, Opts); } } } // namespace targets diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index cba3e3ada7ea..25c02cb888c1 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "AArch64.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/ArrayRef.h" @@ -28,6 +29,10 @@ const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, +#include "clang/Basic/BuiltinsSVE.def" + +#define BUILTIN(ID, TYPE, ATTRS) \ + {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ {#ID, TYPE, ATTRS, nullptr, LANG, nullptr}, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ @@ -65,6 +70,9 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad(); + BFloat16Width = BFloat16Align = 16; + BFloat16Format = &llvm::APFloat::BFloat(); + // Make __builtin_ms_va_list available. HasBuiltinMSVaList = true; @@ -117,15 +125,15 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, return false; BPI.SignReturnAddr = - llvm::StringSwitch<CodeGenOptions::SignReturnAddressScope>(PBP.Scope) - .Case("non-leaf", CodeGenOptions::SignReturnAddressScope::NonLeaf) - .Case("all", CodeGenOptions::SignReturnAddressScope::All) - .Default(CodeGenOptions::SignReturnAddressScope::None); + llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope) + .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf) + .Case("all", LangOptions::SignReturnAddressScopeKind::All) + .Default(LangOptions::SignReturnAddressScopeKind::None); if (PBP.Key == "a_key") - BPI.SignKey = CodeGenOptions::SignReturnAddressKeyValue::AKey; + BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey; else - BPI.SignKey = CodeGenOptions::SignReturnAddressKeyValue::BKey; + BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey; BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; return true; @@ -147,6 +155,7 @@ void AArch64TargetInfo::fillValidCPUList( void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, MacroBuilder &Builder) const { + // FIXME: Armv8.1 makes __ARM_FEATURE_CRC32 mandatory. Handle it here. Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); } @@ -167,17 +176,26 @@ void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts, void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts, MacroBuilder &Builder) const { // Also include the Armv8.3 defines - // FIXME: Armv8.4 makes some extensions mandatory. Handle them here. + // FIXME: Armv8.4 makes __ARM_FEATURE_ATOMICS, defined in GCC, mandatory. + // Add and handle it here. getTargetDefinesARMV83A(Opts, Builder); } void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts, MacroBuilder &Builder) const { // Also include the Armv8.4 defines - // FIXME: Armv8.5 makes some extensions mandatory. Handle them here. getTargetDefinesARMV84A(Opts, Builder); } +void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts, + MacroBuilder &Builder) const { + // Also include the Armv8.5 defines + // FIXME: Armv8.6 makes the following extensions mandatory: + // - __ARM_FEATURE_BF16 + // - __ARM_FEATURE_MATMUL_INT8 + // Handle them here. + getTargetDefinesARMV85A(Opts, Builder); +} void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -194,6 +212,13 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__LP64__"); } + std::string CodeModel = getTargetOpts().CodeModel; + if (CodeModel == "default") + CodeModel = "small"; + for (char &c : CodeModel) + c = toupper(c); + Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__"); + // ACLE predefines. Many can only have one possible value on v8 AArch64. Builder.defineMacro("__ARM_ACLE", "200"); Builder.defineMacro("__ARM_ARCH", "8"); @@ -235,6 +260,24 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__ARM_NEON_FP", "0xE"); } + if (FPU & SveMode) + Builder.defineMacro("__ARM_FEATURE_SVE", "1"); + + if (HasSVE2) + Builder.defineMacro("__ARM_FEATURE_SVE2", "1"); + + if (HasSVE2 && HasSVE2AES) + Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1"); + + if (HasSVE2 && HasSVE2BitPerm) + Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1"); + + if (HasSVE2 && HasSVE2SHA3) + Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1"); + + if (HasSVE2 && HasSVE2SM4) + Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1"); + if (HasCRC) Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); @@ -258,9 +301,53 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasTME) Builder.defineMacro("__ARM_FEATURE_TME", "1"); + if (HasMatMul) + Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1"); + + if (HasBFloat16) { + Builder.defineMacro("__ARM_FEATURE_BF16", "1"); + Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1"); + Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1"); + Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1"); + } + + if ((FPU & SveMode) && HasBFloat16) { + Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1"); + } + + if ((FPU & SveMode) && HasMatmulFP64) + Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1"); + + if ((FPU & SveMode) && HasMatmulFP32) + Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1"); + + if ((FPU & SveMode) && HasMatMul) + Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1"); + if ((FPU & NeonMode) && HasFP16FML) Builder.defineMacro("__ARM_FEATURE_FP16FML", "1"); + if (Opts.hasSignReturnAddress()) { + // Bitmask: + // 0: Protection using the A key + // 1: Protection using the B key + // 2: Protection including leaf functions + unsigned Value = 0; + + if (Opts.isSignReturnAddressWithAKey()) + Value |= (1 << 0); + else + Value |= (1 << 1); + + if (Opts.isSignReturnAddressScopeAll()) + Value |= (1 << 2); + + Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value)); + } + + if (Opts.BranchTargetEnforcement) + Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1"); + switch (ArchKind) { default: break; @@ -279,6 +366,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, case llvm::AArch64::ArchKind::ARMV8_5A: getTargetDefinesARMV85A(Opts, Builder); break; + case llvm::AArch64::ArchKind::ARMV8_6A: + getTargetDefinesARMV86A(Opts, Builder); + break; } // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work. @@ -296,7 +386,11 @@ ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const { bool AArch64TargetInfo::hasFeature(StringRef Feature) const { return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" || (Feature == "neon" && (FPU & NeonMode)) || - (Feature == "sve" && (FPU & SveMode)); + ((Feature == "sve" || Feature == "sve2" || Feature == "sve2-bitperm" || + Feature == "sve2-aes" || Feature == "sve2-sha3" || + Feature == "sve2-sm4" || Feature == "f64mm" || Feature == "f32mm" || + Feature == "i8mm" || Feature == "bf16") && + (FPU & SveMode)); } bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, @@ -310,13 +404,62 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasFP16FML = false; HasMTE = false; HasTME = false; + HasMatMul = false; + HasBFloat16 = false; + HasSVE2 = false; + HasSVE2AES = false; + HasSVE2SHA3 = false; + HasSVE2SM4 = false; + HasSVE2BitPerm = false; + HasMatmulFP64 = false; + HasMatmulFP32 = false; + ArchKind = llvm::AArch64::ArchKind::ARMV8A; for (const auto &Feature : Features) { if (Feature == "+neon") FPU |= NeonMode; - if (Feature == "+sve") + if (Feature == "+sve") { FPU |= SveMode; + HasFullFP16 = 1; + } + if (Feature == "+sve2") { + FPU |= SveMode; + HasFullFP16 = 1; + HasSVE2 = 1; + } + if (Feature == "+sve2-aes") { + FPU |= SveMode; + HasFullFP16 = 1; + HasSVE2 = 1; + HasSVE2AES = 1; + } + if (Feature == "+sve2-sha3") { + FPU |= SveMode; + HasFullFP16 = 1; + HasSVE2 = 1; + HasSVE2SHA3 = 1; + } + if (Feature == "+sve2-sm4") { + FPU |= SveMode; + HasFullFP16 = 1; + HasSVE2 = 1; + HasSVE2SM4 = 1; + } + if (Feature == "+sve2-bitperm") { + FPU |= SveMode; + HasFullFP16 = 1; + HasSVE2 = 1; + HasSVE2BitPerm = 1; + } + if (Feature == "+f32mm") { + FPU |= SveMode; + HasMatmulFP32 = true; + } + if (Feature == "+f64mm") { + FPU |= SveMode; + HasMatmulFP64 = true; + } if (Feature == "+crc") HasCRC = true; if (Feature == "+crypto") @@ -333,6 +476,8 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, ArchKind = llvm::AArch64::ArchKind::ARMV8_4A; if (Feature == "+v8.5a") ArchKind = llvm::AArch64::ArchKind::ARMV8_5A; + if (Feature == "+v8.6a") + ArchKind = llvm::AArch64::ArchKind::ARMV8_6A; if (Feature == "+fullfp16") HasFullFP16 = true; if (Feature == "+dotprod") @@ -343,6 +488,10 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasMTE = true; if (Feature == "+tme") HasTME = true; + if (Feature == "+i8mm") + HasMatMul = true; + if (Feature == "+bf16") + HasBFloat16 = true; } setDataLayout(); @@ -479,17 +628,29 @@ bool AArch64TargetInfo::validateAsmConstraint( Info.setAllowsRegister(); return true; case 'U': + if (Name[1] == 'p' && (Name[2] == 'l' || Name[2] == 'a')) { + // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7) + Info.setAllowsRegister(); + Name += 2; + return true; + } // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes. // Utf: A memory address suitable for ldp/stp in TF mode. // Usa: An absolute symbolic address. // Ush: The high part (bits 32:12) of a pc-relative symbolic address. - llvm_unreachable("FIXME: Unimplemented support for U* constraints."); + + // Better to return an error saying that it's an unrecognised constraint + // even if this is a valid constraint in gcc. + return false; case 'z': // Zero register, wzr or xzr Info.setAllowsRegister(); return true; case 'x': // Floating point and SIMD registers (V0-V15) Info.setAllowsRegister(); return true; + case 'y': // SVE registers (V0-V7) + Info.setAllowsRegister(); + return true; } return false; } diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 5e78237743c9..d1982897d84e 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -36,6 +36,14 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool HasFP16FML; bool HasMTE; bool HasTME; + bool HasMatMul; + bool HasSVE2; + bool HasSVE2AES; + bool HasSVE2SHA3; + bool HasSVE2SM4; + bool HasSVE2BitPerm; + bool HasMatmulFP64; + bool HasMatmulFP32; llvm::AArch64::ArchKind ArchKind; @@ -70,6 +78,8 @@ public: MacroBuilder &Builder) const; void getTargetDefinesARMV85A(const LangOptions &Opts, MacroBuilder &Builder) const; + void getTargetDefinesARMV86A(const LangOptions &Opts, + MacroBuilder &Builder) const; void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; @@ -87,6 +97,21 @@ public: ArrayRef<const char *> getGCCRegNames() const override; ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; + + std::string convertConstraint(const char *&Constraint) const override { + std::string R; + switch (*Constraint) { + case 'U': // Three-character constraint; add "@3" hint for later parsing. + R = std::string("@3") + std::string(Constraint, 3); + Constraint += 2; + break; + default: + R = TargetInfo::convertConstraint(Constraint); + break; + } + return R; + } + bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override; bool @@ -101,7 +126,10 @@ public: int getEHDataRegisterNumber(unsigned RegNo) const override; + const char *getBFloat16Mangling() const override { return "u6__bf16"; }; bool hasInt128Type() const override; + + bool hasExtIntType() const override { return true; } }; class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo { diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index 135ad3f97ce1..db7db8d36d03 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -17,6 +17,7 @@ #include "clang/Basic/MacroBuilder.h" #include "clang/Basic/TargetBuiltins.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Frontend/OpenMP/OMPGridValues.h" #include "llvm/IR/DataLayout.h" using namespace clang; @@ -124,7 +125,36 @@ const char *const AMDGPUTargetInfo::GCCRegNames[] = { "s113", "s114", "s115", "s116", "s117", "s118", "s119", "s120", "s121", "s122", "s123", "s124", "s125", "s126", "s127", "exec", "vcc", "scc", "m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi", - "flat_scratch_lo", "flat_scratch_hi" + "flat_scratch_lo", "flat_scratch_hi", + "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", + "a9", "a10", "a11", "a12", "a13", "a14", "a15", "a16", "a17", + "a18", "a19", "a20", "a21", "a22", "a23", "a24", "a25", "a26", + "a27", "a28", "a29", "a30", "a31", "a32", "a33", "a34", "a35", + "a36", "a37", "a38", "a39", "a40", "a41", "a42", "a43", "a44", + "a45", "a46", "a47", "a48", "a49", "a50", "a51", "a52", "a53", + "a54", "a55", "a56", "a57", "a58", "a59", "a60", "a61", "a62", + "a63", "a64", "a65", "a66", "a67", "a68", "a69", "a70", "a71", + "a72", "a73", "a74", "a75", "a76", "a77", "a78", "a79", "a80", + "a81", "a82", "a83", "a84", "a85", "a86", "a87", "a88", "a89", + "a90", "a91", "a92", "a93", "a94", "a95", "a96", "a97", "a98", + "a99", "a100", "a101", "a102", "a103", "a104", "a105", "a106", "a107", + "a108", "a109", "a110", "a111", "a112", "a113", "a114", "a115", "a116", + "a117", "a118", "a119", "a120", "a121", "a122", "a123", "a124", "a125", + "a126", "a127", "a128", "a129", "a130", "a131", "a132", "a133", "a134", + "a135", "a136", "a137", "a138", "a139", "a140", "a141", "a142", "a143", + "a144", "a145", "a146", "a147", "a148", "a149", "a150", "a151", "a152", + "a153", "a154", "a155", "a156", "a157", "a158", "a159", "a160", "a161", + "a162", "a163", "a164", "a165", "a166", "a167", "a168", "a169", "a170", + "a171", "a172", "a173", "a174", "a175", "a176", "a177", "a178", "a179", + "a180", "a181", "a182", "a183", "a184", "a185", "a186", "a187", "a188", + "a189", "a190", "a191", "a192", "a193", "a194", "a195", "a196", "a197", + "a198", "a199", "a200", "a201", "a202", "a203", "a204", "a205", "a206", + "a207", "a208", "a209", "a210", "a211", "a212", "a213", "a214", "a215", + "a216", "a217", "a218", "a219", "a220", "a221", "a222", "a223", "a224", + "a225", "a226", "a227", "a228", "a229", "a230", "a231", "a232", "a233", + "a234", "a235", "a236", "a237", "a238", "a239", "a240", "a241", "a242", + "a243", "a244", "a245", "a246", "a247", "a248", "a249", "a250", "a251", + "a252", "a253", "a254", "a255" }; ArrayRef<const char *> AMDGPUTargetInfo::getGCCRegNames() const { @@ -140,6 +170,22 @@ bool AMDGPUTargetInfo::initFeatureMap( // XXX - What does the member GPU mean if device name string passed here? if (isAMDGCN(getTriple())) { switch (llvm::AMDGPU::parseArchAMDGCN(CPU)) { + case GK_GFX1030: + Features["ci-insts"] = true; + Features["dot1-insts"] = true; + Features["dot2-insts"] = true; + Features["dot5-insts"] = true; + Features["dot6-insts"] = true; + Features["dl-insts"] = true; + Features["flat-address-space"] = true; + Features["16-bit-insts"] = true; + Features["dpp"] = true; + Features["gfx8-insts"] = true; + Features["gfx9-insts"] = true; + Features["gfx10-insts"] = true; + Features["gfx10-3-insts"] = true; + Features["s-memrealtime"] = true; + break; case GK_GFX1012: case GK_GFX1011: Features["dot1-insts"] = true; @@ -163,6 +209,7 @@ bool AMDGPUTargetInfo::initFeatureMap( Features["dot4-insts"] = true; Features["dot5-insts"] = true; Features["dot6-insts"] = true; + Features["mai-insts"] = true; LLVM_FALLTHROUGH; case GK_GFX906: Features["dl-insts"] = true; @@ -232,27 +279,6 @@ bool AMDGPUTargetInfo::initFeatureMap( return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec); } -void AMDGPUTargetInfo::adjustTargetOptions(const CodeGenOptions &CGOpts, - TargetOptions &TargetOpts) const { - bool hasFP32Denormals = false; - bool hasFP64Denormals = false; - - for (auto &I : TargetOpts.FeaturesAsWritten) { - if (I == "+fp32-denormals" || I == "-fp32-denormals") - hasFP32Denormals = true; - if (I == "+fp64-fp16-denormals" || I == "-fp64-fp16-denormals") - hasFP64Denormals = true; - } - if (!hasFP32Denormals) - TargetOpts.Features.push_back( - (Twine(hasFastFMAF() && hasFullRateDenormalsF32() && !CGOpts.FlushDenorm - ? '+' : '-') + Twine("fp32-denormals")) - .str()); - // Always do not flush fp64 or fp16 denorms. - if (!hasFP64Denormals && hasFP64()) - TargetOpts.Features.push_back("+fp64-fp16-denormals"); -} - void AMDGPUTargetInfo::fillValidCPUList( SmallVectorImpl<StringRef> &Values) const { if (isAMDGCN(getTriple())) @@ -277,6 +303,7 @@ AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple, resetDataLayout(isAMDGCN(getTriple()) ? DataLayoutStringAMDGCN : DataLayoutStringR600); assert(DataLayout->getAllocaAddrSpace() == Private); + GridValues = llvm::omp::AMDGPUGpuGridValues; setAddressSpaceMap(Triple.getOS() == llvm::Triple::Mesa3D || !isAMDGCN(Triple)); @@ -354,4 +381,17 @@ void AMDGPUTargetInfo::setAuxTarget(const TargetInfo *Aux) { copyAuxTarget(Aux); LongDoubleFormat = SaveLongDoubleFormat; Float128Format = SaveFloat128Format; + // For certain builtin types support on the host target, claim they are + // support to pass the compilation of the host code during the device-side + // compilation. + // FIXME: As the side effect, we also accept `__float128` uses in the device + // code. To rejct these builtin types supported in the host target but not in + // the device target, one approach would support `device_builtin` attribute + // so that we could tell the device builtin types from the host ones. The + // also solves the different representations of the same builtin type, such + // as `size_t` in the MSVC environment. + if (Aux->hasFloat128Type()) { + HasFloat128 = true; + Float128Format = DoubleFormat; + } } diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h index 456cb2ebb8b5..d0394492cad6 100644 --- a/clang/lib/Basic/Targets/AMDGPU.h +++ b/clang/lib/Basic/Targets/AMDGPU.h @@ -114,11 +114,14 @@ public: /// Accepted register names: (n, m is unsigned integer, n < m) /// v /// s + /// a /// {vn}, {v[n]} /// {sn}, {s[n]} + /// {an}, {a[n]} /// {S} , where S is a special register name ////{v[n:m]} /// {s[n:m]} + /// {a[n:m]} bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override { static const ::llvm::StringSet<> SpecialRegs({ @@ -127,7 +130,30 @@ public: "exec_hi", "tma_lo", "tma_hi", "tba_lo", "tba_hi", }); + switch (*Name) { + case 'I': + Info.setRequiresImmediate(-16, 64); + return true; + case 'J': + Info.setRequiresImmediate(-32768, 32767); + return true; + case 'A': + case 'B': + case 'C': + Info.setRequiresImmediate(); + return true; + default: + break; + } + StringRef S(Name); + + if (S == "DA" || S == "DB") { + Name++; + Info.setRequiresImmediate(); + return true; + } + bool HasLeftParen = false; if (S.front() == '{') { HasLeftParen = true; @@ -135,7 +161,7 @@ public: } if (S.empty()) return false; - if (S.front() != 'v' && S.front() != 's') { + if (S.front() != 'v' && S.front() != 's' && S.front() != 'a') { if (!HasLeftParen) return false; auto E = S.find('}'); @@ -153,7 +179,7 @@ public: if (!HasLeftParen) { if (!S.empty()) return false; - // Found s or v. + // Found s, v or a. Info.setAllowsRegister(); Name = S.data() - 1; return true; @@ -184,7 +210,8 @@ public: S = S.drop_front(); if (!S.empty()) return false; - // Found {vn}, {sn}, {v[n]}, {s[n]}, {v[n:m]}, or {s[n:m]}. + // Found {vn}, {sn}, {an}, {v[n]}, {s[n]}, {a[n]}, {v[n:m]}, {s[n:m]} + // or {a[n:m]}. Info.setAllowsRegister(); Name = S.data() - 1; return true; @@ -194,6 +221,12 @@ public: // the constraint. In practice, it won't be changed unless the // constraint is longer than one character. std::string convertConstraint(const char *&Constraint) const override { + + StringRef S(Constraint); + if (S == "DA" || S == "DB") { + return std::string("^") + std::string(Constraint++, 2); + } + const char *Begin = Constraint; TargetInfo::ConstraintInfo Info("", ""); if (validateAsmConstraint(Constraint, Info)) @@ -208,11 +241,10 @@ public: StringRef CPU, const std::vector<std::string> &FeatureVec) const override; - void adjustTargetOptions(const CodeGenOptions &CGOpts, - TargetOptions &TargetOpts) const override; - ArrayRef<Builtin::Info> getTargetBuiltins() const override; + bool useFP16ConversionIntrinsics() const override { return false; } + void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; @@ -263,6 +295,7 @@ public: Opts.support("cl_khr_int64_base_atomics"); Opts.support("cl_khr_int64_extended_atomics"); Opts.support("cl_khr_mipmap_image"); + Opts.support("cl_khr_mipmap_image_writes"); Opts.support("cl_khr_subgroups"); Opts.support("cl_khr_3d_image_writes"); Opts.support("cl_amd_media_ops"); @@ -348,10 +381,14 @@ public: // address space has value 0 but in private and local address space has // value ~0. uint64_t getNullPointerValue(LangAS AS) const override { - return AS == LangAS::opencl_local ? ~0 : 0; + // FIXME: Also should handle region. + return (AS == LangAS::opencl_local || AS == LangAS::opencl_private) + ? ~0 : 0; } void setAuxTarget(const TargetInfo *Aux) override; + + bool hasExtIntType() const override { return true; } }; } // namespace targets diff --git a/clang/lib/Basic/Targets/ARC.h b/clang/lib/Basic/Targets/ARC.h index c43a39984edb..b314c42be1e9 100644 --- a/clang/lib/Basic/Targets/ARC.h +++ b/clang/lib/Basic/Targets/ARC.h @@ -65,6 +65,8 @@ public: TargetInfo::ConstraintInfo &Info) const override { return false; } + + bool hasExtIntType() const override { return true; } }; } // namespace targets diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp index be088e81cffe..21cfe0107bbb 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -25,6 +25,9 @@ void ARMTargetInfo::setABIAAPCS() { IsAAPCS = true; DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; + BFloat16Width = BFloat16Align = 16; + BFloat16Format = &llvm::APFloat::BFloat(); + const llvm::Triple &T = getTriple(); bool IsNetBSD = T.isOSNetBSD(); @@ -74,6 +77,8 @@ void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) { DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; else DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32; + BFloat16Width = BFloat16Align = 16; + BFloat16Format = &llvm::APFloat::BFloat(); WCharType = SignedInt; @@ -107,7 +112,7 @@ void ARMTargetInfo::setArchInfo() { StringRef ArchName = getTriple().getArchName(); ArchISA = llvm::ARM::parseArchISA(ArchName); - CPU = llvm::ARM::getDefaultCPU(ArchName); + CPU = std::string(llvm::ARM::getDefaultCPU(ArchName)); llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName); if (AK != llvm::ARM::ArchKind::INVALID) ArchKind = AK; @@ -154,6 +159,8 @@ bool ARMTargetInfo::hasMVEFloat() const { return hasMVE() && (MVE & MVE_FP); } +bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; } + bool ARMTargetInfo::isThumb() const { return ArchISA == llvm::ARM::ISAKind::THUMB; } @@ -199,6 +206,8 @@ StringRef ARMTargetInfo::getCPUAttr() const { return "8_4A"; case llvm::ARM::ArchKind::ARMV8_5A: return "8_5A"; + case llvm::ARM::ArchKind::ARMV8_6A: + return "8_6A"; case llvm::ARM::ArchKind::ARMV8MBaseline: return "8M_BASE"; case llvm::ARM::ArchKind::ARMV8MMainline: @@ -310,7 +319,7 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS) // as well the default alignment - if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android)) + if (IsAAPCS && !Triple.isAndroid()) DefaultAlignForAttributeAligned = MaxVectorAlign = 64; // Do force alignment of members that follow zero length bitfields. If @@ -372,7 +381,7 @@ bool ARMTargetInfo::initFeatureMap( llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures); // get default Extension features - unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch); + uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch); llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures); for (auto Feature : TargetFeatures) @@ -421,7 +430,10 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, // Note that SoftFloatABI is initialized in our constructor. HWDiv = 0; DotProd = 0; + HasMatMul = 0; HasFloat16 = true; + ARMCDECoprocMask = 0; + HasBFloat16 = false; // This does not diagnose illegal cases like having both // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64". @@ -480,14 +492,20 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, } else if (Feature == "+dotprod") { DotProd = true; } else if (Feature == "+mve") { - DSP = 1; MVE |= MVE_INT; } else if (Feature == "+mve.fp") { - DSP = 1; HasLegalHalfType = true; FPU |= FPARMV8; MVE |= MVE_INT | MVE_FP; HW_FP |= HW_FP_SP | HW_FP_HP; + } else if (Feature == "+i8mm") { + HasMatMul = 1; + } else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" && + Feature <= "+cdecp7") { + unsigned Coproc = Feature.back() - '0'; + ARMCDECoprocMask |= (1U << Coproc); + } else if (Feature == "+bf16") { + HasBFloat16 = true; } } @@ -537,6 +555,10 @@ bool ARMTargetInfo::hasFeature(StringRef Feature) const { .Default(false); } +bool ARMTargetInfo::hasBFloat16Type() const { + return HasBFloat16 && !SoftFloat; +} + bool ARMTargetInfo::isValidCPUName(StringRef Name) const { return Name == "generic" || llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID; @@ -760,6 +782,12 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1"); } + if (hasCDE()) { + Builder.defineMacro("__ARM_FEATURE_CDE", "1"); + Builder.defineMacro("__ARM_FEATURE_CDE_COPROC", + "0x" + Twine::utohexstr(getARMCDECoprocMask())); + } + Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", Twine(Opts.WCharSize ? Opts.WCharSize : 4)); @@ -807,6 +835,15 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, if (DotProd) Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1"); + if (HasMatMul) + Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1"); + + if (HasBFloat16) { + Builder.defineMacro("__ARM_FEATURE_BF16", "1"); + Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1"); + Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1"); + } + switch (ArchKind) { default: break; @@ -819,6 +856,7 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, case llvm::ARM::ArchKind::ARMV8_3A: case llvm::ARM::ArchKind::ARMV8_4A: case llvm::ARM::ArchKind::ARMV8_5A: + case llvm::ARM::ArchKind::ARMV8_6A: getTargetDefinesARMV83A(Opts, Builder); break; } diff --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h index 9696a4404589..1e80f74d0766 100644 --- a/clang/lib/Basic/Targets/ARM.h +++ b/clang/lib/Basic/Targets/ARM.h @@ -75,6 +75,7 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { unsigned DSP : 1; unsigned Unaligned : 1; unsigned DotProd : 1; + unsigned HasMatMul : 1; enum { LDREX_B = (1 << 0), /// byte (8-bit) @@ -108,6 +109,7 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { bool supportsThumb2() const; bool hasMVE() const; bool hasMVEFloat() const; + bool hasCDE() const; StringRef getCPUAttr() const; StringRef getCPUProfile() const; @@ -135,6 +137,8 @@ public: bool hasFeature(StringRef Feature) const override; + bool hasBFloat16Type() const override; + bool isValidCPUName(StringRef Name) const override; void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; @@ -180,6 +184,10 @@ public: int getEHDataRegisterNumber(unsigned RegNo) const override; bool hasSjLjLowering() const override; + + bool hasExtIntType() const override { return true; } + + const char *getBFloat16Mangling() const override { return "u6__bf16"; }; }; class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo { diff --git a/clang/lib/Basic/Targets/AVR.cpp b/clang/lib/Basic/Targets/AVR.cpp index d865676700b5..bb215b4114ac 100644 --- a/clang/lib/Basic/Targets/AVR.cpp +++ b/clang/lib/Basic/Targets/AVR.cpp @@ -300,6 +300,7 @@ void AVRTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("AVR"); Builder.defineMacro("__AVR"); Builder.defineMacro("__AVR__"); + Builder.defineMacro("__ELF__"); if (!this->CPU.empty()) { auto It = llvm::find_if( diff --git a/clang/lib/Basic/Targets/BPF.h b/clang/lib/Basic/Targets/BPF.h index b2f1831e960e..43e55dfbfb2b 100644 --- a/clang/lib/Basic/Targets/BPF.h +++ b/clang/lib/Basic/Targets/BPF.h @@ -35,9 +35,9 @@ public: Int64Type = SignedLong; RegParmMax = 5; if (Triple.getArch() == llvm::Triple::bpfeb) { - resetDataLayout("E-m:e-p:64:64-i64:64-n32:64-S128"); + resetDataLayout("E-m:e-p:64:64-i64:64-i128:128-n32:64-S128"); } else { - resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128"); + resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"); } MaxAtomicPromoteWidth = 64; MaxAtomicInlineWidth = 64; diff --git a/clang/lib/Basic/Targets/Hexagon.cpp b/clang/lib/Basic/Targets/Hexagon.cpp index fcb94b93d69d..205601c359d0 100644 --- a/clang/lib/Basic/Targets/Hexagon.cpp +++ b/clang/lib/Basic/Targets/Hexagon.cpp @@ -24,6 +24,11 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__qdsp6__", "1"); Builder.defineMacro("__hexagon__", "1"); + Builder.defineMacro("__ELF__"); + + // The macro __HVXDBL__ is deprecated. + bool DefineHvxDbl = false; + if (CPU == "hexagonv5") { Builder.defineMacro("__HEXAGON_V5__"); Builder.defineMacro("__HEXAGON_ARCH__", "5"); @@ -37,19 +42,29 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__QDSP6_V55__"); Builder.defineMacro("__QDSP6_ARCH__", "55"); } else if (CPU == "hexagonv60") { + DefineHvxDbl = true; Builder.defineMacro("__HEXAGON_V60__"); Builder.defineMacro("__HEXAGON_ARCH__", "60"); Builder.defineMacro("__QDSP6_V60__"); Builder.defineMacro("__QDSP6_ARCH__", "60"); } else if (CPU == "hexagonv62") { + DefineHvxDbl = true; Builder.defineMacro("__HEXAGON_V62__"); Builder.defineMacro("__HEXAGON_ARCH__", "62"); } else if (CPU == "hexagonv65") { + DefineHvxDbl = true; Builder.defineMacro("__HEXAGON_V65__"); Builder.defineMacro("__HEXAGON_ARCH__", "65"); } else if (CPU == "hexagonv66") { + DefineHvxDbl = true; Builder.defineMacro("__HEXAGON_V66__"); Builder.defineMacro("__HEXAGON_ARCH__", "66"); + } else if (CPU == "hexagonv67") { + Builder.defineMacro("__HEXAGON_V67__"); + Builder.defineMacro("__HEXAGON_ARCH__", "67"); + } else if (CPU == "hexagonv67t") { + Builder.defineMacro("__HEXAGON_V67T__"); + Builder.defineMacro("__HEXAGON_ARCH__", "67"); } if (hasFeature("hvx-length64b")) { @@ -62,14 +77,29 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__HVX__"); Builder.defineMacro("__HVX_ARCH__", HVXVersion); Builder.defineMacro("__HVX_LENGTH__", "128"); - // FIXME: This macro is deprecated. - Builder.defineMacro("__HVXDBL__"); + if (DefineHvxDbl) + Builder.defineMacro("__HVXDBL__"); + } + + if (hasFeature("audio")) { + Builder.defineMacro("__HEXAGON_AUDIO__"); } + + std::string NumPhySlots = isTinyCore() ? "3" : "4"; + Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots); } bool HexagonTargetInfo::initFeatureMap( llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeaturesVec) const { + if (isTinyCore()) + Features["audio"] = true; + + StringRef CPUFeature = CPU; + CPUFeature.consume_front("hexagon"); + CPUFeature.consume_back("t"); + Features[CPUFeature] = true; + Features["long-calls"] = false; return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); @@ -91,6 +121,8 @@ bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, UseLongCalls = true; else if (F == "-long-calls") UseLongCalls = false; + else if (F == "+audio") + HasAudio = true; } return true; } @@ -125,6 +157,8 @@ const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, #include "clang/Basic/BuiltinsHexagon.def" }; @@ -139,6 +173,7 @@ bool HexagonTargetInfo::hasFeature(StringRef Feature) const { .Case("hvx-length64b", HasHVX64B) .Case("hvx-length128b", HasHVX128B) .Case("long-calls", UseLongCalls) + .Case("audio", HasAudio) .Default(false); } @@ -148,9 +183,10 @@ struct CPUSuffix { }; static constexpr CPUSuffix Suffixes[] = { - {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}}, - {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}}, - {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}}, + {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}}, + {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}}, + {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}}, + {{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}}, }; const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) { diff --git a/clang/lib/Basic/Targets/Hexagon.h b/clang/lib/Basic/Targets/Hexagon.h index 25a78c181580..d6c7da5f1e40 100644 --- a/clang/lib/Basic/Targets/Hexagon.h +++ b/clang/lib/Basic/Targets/Hexagon.h @@ -32,6 +32,7 @@ class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo { bool HasHVX = false; bool HasHVX64B = false; bool HasHVX128B = false; + bool HasAudio = false; bool UseLongCalls = false; public: @@ -56,6 +57,13 @@ public: LargeArrayAlign = 64; UseBitFieldTypeAlignment = true; ZeroLengthBitfieldBoundary = 32; + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + + // These are the default values anyway, but explicitly make sure + // that the size of the boolean type is 8 bits. Bool vectors are used + // for modeling predicate registers in HVX, and the bool -> byte + // correspondence matches the HVX architecture. + BoolWidth = BoolAlign = 8; } ArrayRef<Builtin::Info> getTargetBuiltins() const override; @@ -96,6 +104,8 @@ public: DiagnosticsEngine &Diags) override; BuiltinVaListKind getBuiltinVaListKind() const override { + if (getTriple().isMusl()) + return TargetInfo::HexagonBuiltinVaList; return TargetInfo::CharPtrBuiltinVaList; } @@ -123,6 +133,13 @@ public: int getEHDataRegisterNumber(unsigned RegNo) const override { return RegNo < 2 ? RegNo : -1; } + + bool isTinyCore() const { + // We can write more stricter checks later. + return CPU.find('t') != std::string::npos; + } + + bool hasExtIntType() const override { return true; } }; } // namespace targets } // namespace clang diff --git a/clang/lib/Basic/Targets/Lanai.h b/clang/lib/Basic/Targets/Lanai.h index e119606384c7..9af5427b81c4 100644 --- a/clang/lib/Basic/Targets/Lanai.h +++ b/clang/lib/Basic/Targets/Lanai.h @@ -86,6 +86,8 @@ public: } const char *getClobbers() const override { return ""; } + + bool hasExtIntType() const override { return true; } }; } // namespace targets } // namespace clang diff --git a/clang/lib/Basic/Targets/MSP430.h b/clang/lib/Basic/Targets/MSP430.h index 620f12d2b8e3..9d42e4d4bb18 100644 --- a/clang/lib/Basic/Targets/MSP430.h +++ b/clang/lib/Basic/Targets/MSP430.h @@ -64,8 +64,14 @@ public: ArrayRef<const char *> getGCCRegNames() const override; ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { - // No aliases. - return None; + // Make r0 - r3 be recognized by llc (f.e., in clobber list) + static const TargetInfo::GCCRegAlias GCCRegAliases[] = { + {{"r0"}, "pc"}, + {{"r1"}, "sp"}, + {{"r2"}, "sr"}, + {{"r3"}, "cg"}, + }; + return llvm::makeArrayRef(GCCRegAliases); } bool validateAsmConstraint(const char *&Name, diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index 224ec0783edf..b475c03889a1 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -406,6 +406,7 @@ public: unsigned getUnwindWordWidth() const override; bool validateTarget(DiagnosticsEngine &Diags) const override; + bool hasExtIntType() const override { return true; } }; } // namespace targets } // namespace clang diff --git a/clang/lib/Basic/Targets/NVPTX.cpp b/clang/lib/Basic/Targets/NVPTX.cpp index f69e9d84c701..18c3c8370331 100644 --- a/clang/lib/Basic/Targets/NVPTX.cpp +++ b/clang/lib/Basic/Targets/NVPTX.cpp @@ -16,6 +16,7 @@ #include "clang/Basic/MacroBuilder.h" #include "clang/Basic/TargetBuiltins.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Frontend/OpenMP/OMPGridValues.h" using namespace clang; using namespace clang::targets; @@ -44,6 +45,8 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, if (!Feature.startswith("+ptx")) continue; PTXVersion = llvm::StringSwitch<unsigned>(Feature) + .Case("+ptx70", 70) + .Case("+ptx65", 65) .Case("+ptx64", 64) .Case("+ptx63", 63) .Case("+ptx61", 61) @@ -60,6 +63,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, TLSSupported = false; VLASupported = false; AddrSpaceMap = &NVPTXAddrSpaceMap; + GridValues = llvm::omp::NVPTXGpuGridValues; UseAddrSpaceMapMangling = true; // Define available target features @@ -196,6 +200,7 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, case CudaArch::GFX1010: case CudaArch::GFX1011: case CudaArch::GFX1012: + case CudaArch::GFX1030: case CudaArch::LAST: break; case CudaArch::UNKNOWN: @@ -231,6 +236,8 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, return "720"; case CudaArch::SM_75: return "750"; + case CudaArch::SM_80: + return "800"; } llvm_unreachable("unhandled CudaArch"); }(); diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h index 63780789c474..f57a0f18efa3 100644 --- a/clang/lib/Basic/Targets/NVPTX.h +++ b/clang/lib/Basic/Targets/NVPTX.h @@ -160,6 +160,8 @@ public: return HostTarget->checkCallingConvention(CC); return CCCR_Warning; } + + bool hasExtIntType() const override { return true; } }; } // namespace targets } // namespace clang diff --git a/clang/lib/Basic/Targets/OSTargets.cpp b/clang/lib/Basic/Targets/OSTargets.cpp index d4ffffc64ba8..15e475a31d64 100644 --- a/clang/lib/Basic/Targets/OSTargets.cpp +++ b/clang/lib/Basic/Targets/OSTargets.cpp @@ -25,7 +25,7 @@ void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, Builder.defineMacro("__APPLE_CC__", "6000"); Builder.defineMacro("__APPLE__"); Builder.defineMacro("__STDC_NO_THREADS__"); - Builder.defineMacro("OBJC_NEW_PROPERTIES"); + // AddressSanitizer doesn't play well with source fortification, which is on // by default on Darwin. if (Opts.Sanitize.has(SanitizerKind::Address)) @@ -179,7 +179,7 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) { Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1)); if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) { - if (Opts.CPlusPlus2a) + if (Opts.CPlusPlus20) Builder.defineMacro("_MSVC_LANG", "201705L"); else if (Opts.CPlusPlus17) Builder.defineMacro("_MSVC_LANG", "201703L"); diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 70fac030bc5d..cfa362bef1b1 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -87,7 +87,7 @@ protected: public: DarwinTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : OSTargetInfo<Target>(Triple, Opts) { - // By default, no TLS, and we whitelist permitted architecture/OS + // By default, no TLS, and we list permitted architecture/OS // combinations. this->TLSSupported = false; @@ -706,6 +706,8 @@ protected: public: AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : OSTargetInfo<Target>(Triple, Opts) { + this->TheCXXABI.set(TargetCXXABI::XL); + if (this->PointerWidth == 64) { this->WCharType = this->UnsignedInt; } else { @@ -819,7 +821,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo : public OSTargetInfo<Target> { protected: void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, - MacroBuilder &Builder) const { + MacroBuilder &Builder) const override { // A common platform macro. if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); diff --git a/clang/lib/Basic/Targets/PNaCl.h b/clang/lib/Basic/Targets/PNaCl.h index ab4abf9fc567..d5bfc369583f 100644 --- a/clang/lib/Basic/Targets/PNaCl.h +++ b/clang/lib/Basic/Targets/PNaCl.h @@ -68,6 +68,8 @@ public: } const char *getClobbers() const override { return ""; } + + bool hasExtIntType() const override { return true; } }; // We attempt to use PNaCl (le32) frontend and Mips32EL backend. diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 1877d4a5ef70..f0de2bf070ea 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -54,6 +54,10 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasFloat128 = true; } else if (Feature == "+power9-vector") { HasP9Vector = true; + } else if (Feature == "+power10-vector") { + HasP10Vector = true; + } else if (Feature == "+pcrelative-memops") { + HasPCRelativeMemops = true; } else if (Feature == "+spe") { HasSPE = true; LongDoubleWidth = LongDoubleAlign = 64; @@ -151,6 +155,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("_ARCH_PWR8"); if (ArchDefs & ArchDefinePwr9) Builder.defineMacro("_ARCH_PWR9"); + if (ArchDefs & ArchDefinePwr10) + Builder.defineMacro("_ARCH_PWR10"); if (ArchDefs & ArchDefineA2) Builder.defineMacro("_ARCH_A2"); if (ArchDefs & ArchDefineA2q) { @@ -189,6 +195,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__FLOAT128__"); if (HasP9Vector) Builder.defineMacro("__POWER9_VECTOR__"); + if (HasP10Vector) + Builder.defineMacro("__POWER10_VECTOR__"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); @@ -223,38 +231,32 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, // - direct-move // - float128 // - power9-vector +// - power10-vector // then go ahead and error since the customer has expressed an incompatible // set of options. static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, const std::vector<std::string> &FeaturesVec) { - if (llvm::find(FeaturesVec, "-vsx") != FeaturesVec.end()) { - if (llvm::find(FeaturesVec, "+power8-vector") != FeaturesVec.end()) { - Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower8-vector" - << "-mno-vsx"; - return false; - } - - if (llvm::find(FeaturesVec, "+direct-move") != FeaturesVec.end()) { - Diags.Report(diag::err_opt_not_valid_with_opt) << "-mdirect-move" - << "-mno-vsx"; - return false; - } + // vsx was not explicitly turned off. + if (llvm::find(FeaturesVec, "-vsx") == FeaturesVec.end()) + return true; - if (llvm::find(FeaturesVec, "+float128") != FeaturesVec.end()) { - Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" - << "-mno-vsx"; - return false; + auto FindVSXSubfeature = [&](StringRef Feature, StringRef Option) { + if (llvm::find(FeaturesVec, Feature) != FeaturesVec.end()) { + Diags.Report(diag::err_opt_not_valid_with_opt) << Option << "-mno-vsx"; + return true; } + return false; + }; - if (llvm::find(FeaturesVec, "+power9-vector") != FeaturesVec.end()) { - Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower9-vector" - << "-mno-vsx"; - return false; - } - } + bool Found = FindVSXSubfeature("+power8-vector", "-mpower8-vector"); + Found |= FindVSXSubfeature("+direct-move", "-mdirect-move"); + Found |= FindVSXSubfeature("+float128", "-mfloat128"); + Found |= FindVSXSubfeature("+power9-vector", "-mpower9-vector"); + Found |= FindVSXSubfeature("+power10-vector", "-mpower10-vector"); - return true; + // Return false if any vsx subfeatures was found. + return !Found; } bool PPCTargetInfo::initFeatureMap( @@ -321,10 +323,17 @@ bool PPCTargetInfo::initFeatureMap( .Case("e500", true) .Default(false); - // Future CPU should include all of the features of Power 9 as well as any + // 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); + } + + // Future CPU should include all of the features of Power 10 as well as any // additional features (yet to be determined) specific to it. if (CPU == "future") { - initFeatureMap(Features, Diags, "pwr9", FeaturesVec); + initFeatureMap(Features, Diags, "pwr10", FeaturesVec); addFutureSpecificFeatures(Features); } @@ -341,6 +350,15 @@ 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["power10-vector"] = true; + Features["pcrelative-memops"] = true; + return; +} + // Add features specific to the "Future" CPU. void PPCTargetInfo::addFutureSpecificFeatures( llvm::StringMap<bool> &Features) const { @@ -361,6 +379,8 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const { .Case("extdiv", HasExtDiv) .Case("float128", HasFloat128) .Case("power9-vector", HasP9Vector) + .Case("power10-vector", HasP10Vector) + .Case("pcrelative-memops", HasPCRelativeMemops) .Case("spe", HasSPE) .Default(false); } @@ -375,22 +395,34 @@ void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, .Case("direct-move", true) .Case("power8-vector", true) .Case("power9-vector", true) + .Case("power10-vector", true) .Case("float128", true) .Default(false); if (FeatureHasVSX) Features["vsx"] = Features["altivec"] = true; if (Name == "power9-vector") Features["power8-vector"] = true; - Features[Name] = true; + else if (Name == "power10-vector") + Features["power8-vector"] = Features["power9-vector"] = true; + if (Name == "pcrel") + Features["pcrelative-memops"] = true; + else + Features[Name] = true; } else { // If we're disabling altivec or vsx go ahead and disable all of the vsx // features. if ((Name == "altivec") || (Name == "vsx")) Features["vsx"] = Features["direct-move"] = Features["power8-vector"] = - Features["float128"] = Features["power9-vector"] = false; + Features["float128"] = Features["power9-vector"] = + Features["power10-vector"] = false; if (Name == "power8-vector") - Features["power9-vector"] = false; - Features[Name] = false; + Features["power9-vector"] = Features["power10-vector"] = false; + else if (Name == "power9-vector") + Features["power10-vector"] = false; + if (Name == "pcrel") + Features["pcrelative-memops"] = false; + else + Features[Name] = false; } } @@ -471,18 +503,17 @@ ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const { } static constexpr llvm::StringLiteral ValidCPUNames[] = { - {"generic"}, {"440"}, {"450"}, {"601"}, {"602"}, - {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"}, - {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"}, - {"7450"}, {"g4+"}, {"750"}, {"8548"}, {"970"}, - {"g5"}, {"a2"}, {"a2q"}, {"e500"}, {"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"}, - {"future"} -}; + {"generic"}, {"440"}, {"450"}, {"601"}, {"602"}, + {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"}, + {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"}, + {"7450"}, {"g4+"}, {"750"}, {"8548"}, {"970"}, + {"g5"}, {"a2"}, {"a2q"}, {"e500"}, {"e500mc"}, + {"e5500"}, {"power3"}, {"pwr3"}, {"power4"}, {"pwr4"}, + {"power5"}, {"pwr5"}, {"power5x"}, {"pwr5x"}, {"power6"}, + {"pwr6"}, {"power6x"}, {"pwr6x"}, {"power7"}, {"pwr7"}, + {"power8"}, {"pwr8"}, {"power9"}, {"pwr9"}, {"power10"}, + {"pwr10"}, {"powerpc"}, {"ppc"}, {"powerpc64"}, {"ppc64"}, + {"powerpc64le"}, {"ppc64le"}, {"future"}}; bool PPCTargetInfo::isValidCPUName(StringRef Name) const { return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 270aa7ff9181..858059bacb86 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -43,13 +43,13 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { ArchDefinePwr7 = 1 << 11, ArchDefinePwr8 = 1 << 12, ArchDefinePwr9 = 1 << 13, - ArchDefineFuture = 1 << 14, - ArchDefineA2 = 1 << 15, - ArchDefineA2q = 1 << 16, - ArchDefineE500 = 1 << 17 + ArchDefinePwr10 = 1 << 14, + ArchDefineFuture = 1 << 15, + ArchDefineA2 = 1 << 16, + ArchDefineA2q = 1 << 17, + ArchDefineE500 = 1 << 18 } ArchDefineTypes; - ArchDefineTypes ArchDefs = ArchDefineNone; static const Builtin::Info BuiltinInfo[]; static const char *const GCCRegNames[]; @@ -69,6 +69,8 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { bool HasExtDiv = false; bool HasP9Vector = false; bool HasSPE = false; + bool HasP10Vector = false; + bool HasPCRelativeMemops = false; protected: std::string ABI; @@ -119,20 +121,20 @@ public: .Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q) .Cases("power3", "pwr3", ArchDefinePpcgr) .Cases("power4", "pwr4", - ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) .Cases("power5", "pwr5", - ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | - ArchDefinePpcsq) + ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | + ArchDefinePpcsq) .Cases("power5x", "pwr5x", - ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | - ArchDefinePpcgr | ArchDefinePpcsq) + ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | + ArchDefinePpcgr | ArchDefinePpcsq) .Cases("power6", "pwr6", - ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | - ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | + ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) .Cases("power6x", "pwr6x", - ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x | - ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | - ArchDefinePpcsq) + ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x | + ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | + ArchDefinePpcsq) .Cases("power7", "pwr7", ArchDefinePwr7 | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | @@ -146,11 +148,16 @@ public: ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + .Cases("power10", "pwr10", + ArchDefinePwr10 | ArchDefinePwr9 | ArchDefinePwr8 | + ArchDefinePwr7 | ArchDefinePwr6 | ArchDefinePwr5x | + ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | + ArchDefinePpcsq) .Case("future", - ArchDefineFuture | ArchDefinePwr9 | ArchDefinePwr8 | - ArchDefinePwr7 | ArchDefinePwr6 | ArchDefinePwr5x | - ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | - ArchDefinePpcsq) + ArchDefineFuture | ArchDefinePwr10 | ArchDefinePwr9 | + ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6 | + ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | + ArchDefinePpcgr | ArchDefinePpcsq) .Cases("8548", "e500", ArchDefineE500) .Default(ArchDefineNone); } @@ -171,6 +178,7 @@ public: StringRef CPU, const std::vector<std::string> &FeaturesVec) const override; + void addP10SpecificFeatures(llvm::StringMap<bool> &Features) const; void addFutureSpecificFeatures(llvm::StringMap<bool> &Features) const; bool handleTargetFeatures(std::vector<std::string> &Features, @@ -276,11 +284,12 @@ public: break; case 'Q': // Memory operand that is an offset from a register (it is // usually better to use `m' or `es' in asm statements) + Info.setAllowsRegister(); + LLVM_FALLTHROUGH; case 'Z': // Memory operand that is an indexed or indirect from a // register (it is usually better to use `m' or `es' in // asm statements) Info.setAllowsMemory(); - Info.setAllowsRegister(); break; case 'R': // AIX TOC entry case 'a': // Address operand that is an indexed or indirect from a @@ -332,13 +341,22 @@ public: : "u9__ieee128"; } const char *getFloat128Mangling() const override { return "u9__ieee128"; } + + bool hasExtIntType() const override { return true; } + + bool isSPRegName(StringRef RegName) const override { + return RegName.equals("r1") || RegName.equals("x1"); + } }; class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo { public: PPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : PPCTargetInfo(Triple, Opts) { - resetDataLayout("E-m:e-p:32:32-i64:64-n32"); + if (Triple.isOSAIX()) + resetDataLayout("E-m:a-p:32:32-i64:64-n32"); + else + resetDataLayout("E-m:e-p:32:32-i64:64-n32"); switch (getTriple().getOS()) { case llvm::Triple::Linux: @@ -384,7 +402,11 @@ public: IntMaxType = SignedLong; Int64Type = SignedLong; - if ((Triple.getArch() == llvm::Triple::ppc64le)) { + if (Triple.isOSAIX()) { + // TODO: Set appropriate ABI for AIX platform. + resetDataLayout("E-m:a-i64:64-n32:64"); + SuitableAlign = 64; + } else if ((Triple.getArch() == llvm::Triple::ppc64le)) { resetDataLayout("e-m:e-i64:64-n32:64"); ABI = "elfv2"; } else { @@ -392,9 +414,6 @@ public: ABI = "elfv1"; } - if (Triple.getOS() == llvm::Triple::AIX) - SuitableAlign = 64; - if (Triple.isOSFreeBSD() || Triple.getOS() == llvm::Triple::AIX || Triple.isMusl()) { LongDoubleWidth = LongDoubleAlign = 64; diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index ab8272c034fd..522776437cd2 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -125,6 +125,9 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, if (HasC) Builder.defineMacro("__riscv_compressed"); + + if (HasB) + Builder.defineMacro("__riscv_bitmanip"); } /// Return true if has this feature, need to sync with handleTargetFeatures. @@ -139,6 +142,7 @@ bool RISCVTargetInfo::hasFeature(StringRef Feature) const { .Case("f", HasF) .Case("d", HasD) .Case("c", HasC) + .Case("experimental-b", HasB) .Default(false); } @@ -156,6 +160,8 @@ bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasD = true; else if (Feature == "+c") HasC = true; + else if (Feature == "+experimental-b") + HasB = true; } return true; diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h index 9118494a87ab..73652b409e9c 100644 --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -30,11 +30,12 @@ protected: bool HasF; bool HasD; bool HasC; + bool HasB; public: RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple), HasM(false), HasA(false), HasF(false), - HasD(false), HasC(false) { + HasD(false), HasC(false), HasB(false) { LongDoubleWidth = 128; LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad(); @@ -75,6 +76,8 @@ public: bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override; + + bool hasExtIntType() const override { return true; } }; class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo { public: diff --git a/clang/lib/Basic/Targets/SPIR.cpp b/clang/lib/Basic/Targets/SPIR.cpp index a9b815d13bc1..9b7aab85314a 100644 --- a/clang/lib/Basic/Targets/SPIR.cpp +++ b/clang/lib/Basic/Targets/SPIR.cpp @@ -23,10 +23,12 @@ void SPIRTargetInfo::getTargetDefines(const LangOptions &Opts, void SPIR32TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { + SPIRTargetInfo::getTargetDefines(Opts, Builder); DefineStd(Builder, "SPIR32", Opts); } void SPIR64TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { + SPIRTargetInfo::getTargetDefines(Opts, Builder); DefineStd(Builder, "SPIR64", Opts); } diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 279d1866a428..f625d4980e29 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -100,6 +100,8 @@ public: // for SPIR since it is a generic target. getSupportedOpenCLOpts().supportAll(); } + + bool hasExtIntType() const override { return true; } }; class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo { public: diff --git a/clang/lib/Basic/Targets/Sparc.h b/clang/lib/Basic/Targets/Sparc.h index 1f799565e99b..d24cf15d7cd6 100644 --- a/clang/lib/Basic/Targets/Sparc.h +++ b/clang/lib/Basic/Targets/Sparc.h @@ -176,6 +176,7 @@ public: MacroBuilder &Builder) const override; bool hasSjLjLowering() const override { return true; } + bool hasExtIntType() const override { return true; } }; // SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel. @@ -227,6 +228,8 @@ public: return false; return getCPUGeneration(CPU) == CG_V9; } + + bool hasExtIntType() const override { return true; } }; } // namespace targets } // namespace clang diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index e751806f4747..d7869e3754a8 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -29,11 +29,12 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { int ISARevision; bool HasTransactionalExecution; bool HasVector; + bool SoftFloat; public: SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple), CPU("z10"), ISARevision(8), - HasTransactionalExecution(false), HasVector(false) { + HasTransactionalExecution(false), HasVector(false), SoftFloat(false) { IntMaxType = SignedLong; Int64Type = SignedLong; TLSSupported = true; @@ -47,6 +48,7 @@ public: MinGlobalAlign = 16; resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + HasStrictFP = true; } void getTargetDefines(const LangOptions &Opts, @@ -63,6 +65,10 @@ public: ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; + bool isSPRegName(StringRef RegName) const override { + return RegName.equals("r15"); + } + bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override; @@ -109,12 +115,17 @@ public: DiagnosticsEngine &Diags) override { HasTransactionalExecution = false; HasVector = false; + SoftFloat = false; for (const auto &Feature : Features) { if (Feature == "+transactional-execution") HasTransactionalExecution = true; else if (Feature == "+vector") HasVector = true; + else if (Feature == "+soft-float") + SoftFloat = true; } + HasVector &= !SoftFloat; + // If we use the vector ABI, vector types are 64-bit aligned. if (HasVector) { MaxVectorAlign = 64; @@ -144,6 +155,8 @@ public: } const char *getLongDoubleMangling() const override { return "g"; } + + bool hasExtIntType() const override { return true; } }; } // namespace targets } // namespace clang diff --git a/clang/lib/Basic/Targets/VE.cpp b/clang/lib/Basic/Targets/VE.cpp new file mode 100644 index 000000000000..22223654e8ad --- /dev/null +++ b/clang/lib/Basic/Targets/VE.cpp @@ -0,0 +1,39 @@ +//===--- VE.cpp - Implement VE target feature support ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements VE TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#include "VE.h" +#include "clang/Basic/Builtins.h" +#include "clang/Basic/MacroBuilder.h" +#include "clang/Basic/TargetBuiltins.h" + +using namespace clang; +using namespace clang::targets; + +void VETargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + Builder.defineMacro("_LP64", "1"); + Builder.defineMacro("unix", "1"); + Builder.defineMacro("__unix__", "1"); + Builder.defineMacro("__linux__", "1"); + Builder.defineMacro("__ve", "1"); + Builder.defineMacro("__ve__", "1"); + Builder.defineMacro("__STDC_HOSTED__", "1"); + Builder.defineMacro("__STDC__", "1"); + Builder.defineMacro("__NEC__", "1"); + // FIXME: define __FAST_MATH__ 1 if -ffast-math is enabled + // FIXME: define __OPTIMIZE__ n if -On is enabled + // FIXME: define __VECTOR__ n 1 if automatic vectorization is enabled +} + +ArrayRef<Builtin::Info> VETargetInfo::getTargetBuiltins() const { + return ArrayRef<Builtin::Info>(); +} diff --git a/clang/lib/Basic/Targets/VE.h b/clang/lib/Basic/Targets/VE.h new file mode 100644 index 000000000000..f863a0af0acb --- /dev/null +++ b/clang/lib/Basic/Targets/VE.h @@ -0,0 +1,170 @@ +//===--- VE.h - Declare VE target feature support ---------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares VE TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_VE_H +#define LLVM_CLANG_LIB_BASIC_TARGETS_VE_H + +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/Compiler.h" + +namespace clang { +namespace targets { + +class LLVM_LIBRARY_VISIBILITY VETargetInfo : public TargetInfo { + static const Builtin::Info BuiltinInfo[]; + +public: + VETargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { + NoAsmVariants = true; + LongDoubleWidth = 128; + LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); + DoubleAlign = LongLongAlign = 64; + SuitableAlign = 64; + LongWidth = LongAlign = PointerWidth = PointerAlign = 64; + SizeType = UnsignedLong; + PtrDiffType = SignedLong; + IntPtrType = SignedLong; + IntMaxType = SignedLong; + Int64Type = SignedLong; + RegParmMax = 8; + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + + WCharType = UnsignedInt; + WIntType = UnsignedInt; + UseZeroLengthBitfieldAlignment = true; + resetDataLayout("e-m:e-i64:64-n32:64-S128"); + } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; + + bool hasSjLjLowering() const override { + // TODO + return false; + } + + ArrayRef<Builtin::Info> getTargetBuiltins() const override; + + BuiltinVaListKind getBuiltinVaListKind() const override { + return TargetInfo::VoidPtrBuiltinVaList; + } + + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + switch (CC) { + default: + return CCCR_Warning; + case CC_C: + return CCCR_OK; + } + } + + const char *getClobbers() const override { return ""; } + + ArrayRef<const char *> getGCCRegNames() const override { + static const char *const GCCRegNames[] = { + // Regular registers + "sx0", "sx1", "sx2", "sx3", "sx4", "sx5", "sx6", "sx7", + "sx8", "sx9", "sx10", "sx11", "sx12", "sx13", "sx14", "sx15", + "sx16", "sx17", "sx18", "sx19", "sx20", "sx21", "sx22", "sx23", + "sx24", "sx25", "sx26", "sx27", "sx28", "sx29", "sx30", "sx31", + "sx32", "sx33", "sx34", "sx35", "sx36", "sx37", "sx38", "sx39", + "sx40", "sx41", "sx42", "sx43", "sx44", "sx45", "sx46", "sx47", + "sx48", "sx49", "sx50", "sx51", "sx52", "sx53", "sx54", "sx55", + "sx56", "sx57", "sx58", "sx59", "sx60", "sx61", "sx62", "sx63", + }; + return llvm::makeArrayRef(GCCRegNames); + } + + ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { + static const TargetInfo::GCCRegAlias GCCRegAliases[] = { + {{"s0"}, "sx0"}, + {{"s1"}, "sx1"}, + {{"s2"}, "sx2"}, + {{"s3"}, "sx3"}, + {{"s4"}, "sx4"}, + {{"s5"}, "sx5"}, + {{"s6"}, "sx6"}, + {{"s7"}, "sx7"}, + {{"s8", "sl"}, "sx8"}, + {{"s9", "fp"}, "sx9"}, + {{"s10", "lr"}, "sx10"}, + {{"s11", "sp"}, "sx11"}, + {{"s12", "outer"}, "sx12"}, + {{"s13"}, "sx13"}, + {{"s14", "tp"}, "sx14"}, + {{"s15", "got"}, "sx15"}, + {{"s16", "plt"}, "sx16"}, + {{"s17", "info"}, "sx17"}, + {{"s18"}, "sx18"}, + {{"s19"}, "sx19"}, + {{"s20"}, "sx20"}, + {{"s21"}, "sx21"}, + {{"s22"}, "sx22"}, + {{"s23"}, "sx23"}, + {{"s24"}, "sx24"}, + {{"s25"}, "sx25"}, + {{"s26"}, "sx26"}, + {{"s27"}, "sx27"}, + {{"s28"}, "sx28"}, + {{"s29"}, "sx29"}, + {{"s30"}, "sx30"}, + {{"s31"}, "sx31"}, + {{"s32"}, "sx32"}, + {{"s33"}, "sx33"}, + {{"s34"}, "sx34"}, + {{"s35"}, "sx35"}, + {{"s36"}, "sx36"}, + {{"s37"}, "sx37"}, + {{"s38"}, "sx38"}, + {{"s39"}, "sx39"}, + {{"s40"}, "sx40"}, + {{"s41"}, "sx41"}, + {{"s42"}, "sx42"}, + {{"s43"}, "sx43"}, + {{"s44"}, "sx44"}, + {{"s45"}, "sx45"}, + {{"s46"}, "sx46"}, + {{"s47"}, "sx47"}, + {{"s48"}, "sx48"}, + {{"s49"}, "sx49"}, + {{"s50"}, "sx50"}, + {{"s51"}, "sx51"}, + {{"s52"}, "sx52"}, + {{"s53"}, "sx53"}, + {{"s54"}, "sx54"}, + {{"s55"}, "sx55"}, + {{"s56"}, "sx56"}, + {{"s57"}, "sx57"}, + {{"s58"}, "sx58"}, + {{"s59"}, "sx59"}, + {{"s60"}, "sx60"}, + {{"s61"}, "sx61"}, + {{"s62"}, "sx62"}, + {{"s63"}, "sx63"}, + }; + return llvm::makeArrayRef(GCCRegAliases); + } + + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const override { + return false; + } + + bool allowsLargerPreferedTypeAlignment() const override { return false; } +}; +} // namespace targets +} // namespace clang +#endif // LLVM_CLANG_LIB_BASIC_TARGETS_VE_H diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp index b16442b99b62..6746768090f5 100644 --- a/clang/lib/Basic/Targets/WebAssembly.cpp +++ b/clang/lib/Basic/Targets/WebAssembly.cpp @@ -33,6 +33,16 @@ const Builtin::Info WebAssemblyTargetInfo::BuiltinInfo[] = { static constexpr llvm::StringLiteral ValidCPUNames[] = { {"mvp"}, {"bleeding-edge"}, {"generic"}}; +StringRef WebAssemblyTargetInfo::getABI() const { return ABI; } + +bool WebAssemblyTargetInfo::setABI(const std::string &Name) { + if (Name != "mvp" && Name != "experimental-mv") + return false; + + ABI = Name; + return true; +} + bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch<bool>(Feature) .Case("simd128", SIMDLevel >= SIMD128) @@ -45,6 +55,7 @@ bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const { .Case("mutable-globals", HasMutableGlobals) .Case("multivalue", HasMultivalue) .Case("tail-call", HasTailCall) + .Case("reference-types", HasReferenceTypes) .Default(false); } @@ -80,6 +91,8 @@ void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__wasm_multivalue__"); if (HasTailCall) Builder.defineMacro("__wasm_tail_call__"); + if (HasReferenceTypes) + Builder.defineMacro("__wasm_reference_types__"); } void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap<bool> &Features, @@ -102,8 +115,10 @@ bool WebAssemblyTargetInfo::initFeatureMap( if (CPU == "bleeding-edge") { Features["nontrapping-fptoint"] = true; Features["sign-ext"] = true; + Features["bulk-memory"] = true; Features["atomics"] = true; Features["mutable-globals"] = true; + Features["tail-call"] = true; setSIMDLevel(Features, SIMD128); } // Other targets do not consider user-configured features here, but while we @@ -126,6 +141,8 @@ bool WebAssemblyTargetInfo::initFeatureMap( Features["multivalue"] = true; if (HasTailCall) Features["tail-call"] = true; + if (HasReferenceTypes) + Features["reference-types"] = true; return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } @@ -213,6 +230,14 @@ bool WebAssemblyTargetInfo::handleTargetFeatures( HasTailCall = false; continue; } + if (Feature == "+reference-types") { + HasReferenceTypes = true; + continue; + } + if (Feature == "-reference-types") { + HasReferenceTypes = false; + continue; + } Diags.Report(diag::err_opt_not_valid_with_opt) << Feature << "-target-feature"; diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index 9665156b143f..77a2fe9ae117 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -38,6 +38,9 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo { bool HasMutableGlobals = false; bool HasMultivalue = false; bool HasTailCall = false; + bool HasReferenceTypes = false; + + std::string ABI; public: explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &) @@ -58,6 +61,9 @@ public: IntPtrType = SignedLong; } + StringRef getABI() const override; + bool setABI(const std::string &Name) override; + protected: void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; @@ -114,7 +120,22 @@ private: ? (IsSigned ? SignedLongLong : UnsignedLongLong) : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned); } + + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + switch (CC) { + case CC_C: + case CC_Swift: + return CCCR_OK; + default: + return CCCR_Warning; + } + } + + bool hasExtIntType() const override { return true; } + + bool hasProtectedVisibility() const override { return false; } }; + class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo : public WebAssemblyTargetInfo { public: diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index d099d3742f0b..543f232d2459 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -17,7 +17,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/TargetParser.h" +#include "llvm/Support/X86TargetParser.h" namespace clang { namespace targets { @@ -62,6 +62,7 @@ static const char *const GCCRegNames[] = { "cr0", "cr2", "cr3", "cr4", "cr8", "dr0", "dr1", "dr2", "dr3", "dr6", "dr7", "bnd0", "bnd1", "bnd2", "bnd3", + "tmm0", "tmm1", "tmm2", "tmm3", "tmm4", "tmm5", "tmm6", "tmm7", }; const TargetInfo::AddlRegName AddlRegNames[] = { @@ -107,339 +108,15 @@ bool X86TargetInfo::initFeatureMap( // FIXME: This *really* should not be here. // X86_64 always has SSE2. if (getTriple().getArch() == llvm::Triple::x86_64) - setFeatureEnabledImpl(Features, "sse2", true); + setFeatureEnabled(Features, "sse2", true); - const CPUKind Kind = getCPUKind(CPU); + using namespace llvm::X86; - // Enable X87 for all X86 processors but Lakemont. - if (Kind != CK_Lakemont) - setFeatureEnabledImpl(Features, "x87", true); + SmallVector<StringRef, 16> CPUFeatures; + getFeaturesForCPU(CPU, CPUFeatures); + for (auto &F : CPUFeatures) + setFeatureEnabled(Features, F, true); - // Enable cmpxchg8 for i586 and greater CPUs. Include generic for backwards - // compatibility. - if (Kind >= CK_i586 || Kind == CK_Generic) - setFeatureEnabledImpl(Features, "cx8", true); - - switch (Kind) { - case CK_Generic: - case CK_i386: - case CK_i486: - case CK_i586: - case CK_Pentium: - case CK_PentiumPro: - case CK_i686: - case CK_Lakemont: - break; - - case CK_Cooperlake: - // CPX inherits all CLX features plus AVX512BF16 - setFeatureEnabledImpl(Features, "avx512bf16", true); - LLVM_FALLTHROUGH; - case CK_Cascadelake: - // CLX inherits all SKX features plus AVX512VNNI - setFeatureEnabledImpl(Features, "avx512vnni", true); - LLVM_FALLTHROUGH; - case CK_SkylakeServer: - setFeatureEnabledImpl(Features, "avx512f", true); - setFeatureEnabledImpl(Features, "avx512cd", true); - setFeatureEnabledImpl(Features, "avx512dq", true); - setFeatureEnabledImpl(Features, "avx512bw", true); - setFeatureEnabledImpl(Features, "avx512vl", true); - setFeatureEnabledImpl(Features, "clwb", true); - setFeatureEnabledImpl(Features, "pku", true); - // SkylakeServer cores inherits all SKL features, except SGX - goto SkylakeCommon; - - case CK_Tigerlake: - setFeatureEnabledImpl(Features, "avx512vp2intersect", true); - setFeatureEnabledImpl(Features, "movdiri", true); - setFeatureEnabledImpl(Features, "movdir64b", true); - setFeatureEnabledImpl(Features, "shstk", true); - // Tigerlake cores inherits IcelakeClient, except pconfig and wbnoinvd - goto IcelakeCommon; - - case CK_IcelakeServer: - setFeatureEnabledImpl(Features, "pconfig", true); - setFeatureEnabledImpl(Features, "wbnoinvd", true); - LLVM_FALLTHROUGH; - case CK_IcelakeClient: -IcelakeCommon: - setFeatureEnabledImpl(Features, "vaes", true); - setFeatureEnabledImpl(Features, "gfni", true); - setFeatureEnabledImpl(Features, "vpclmulqdq", true); - setFeatureEnabledImpl(Features, "avx512bitalg", true); - setFeatureEnabledImpl(Features, "avx512vbmi2", true); - setFeatureEnabledImpl(Features, "avx512vnni", true); - setFeatureEnabledImpl(Features, "avx512vpopcntdq", true); - setFeatureEnabledImpl(Features, "rdpid", true); - setFeatureEnabledImpl(Features, "clwb", true); - LLVM_FALLTHROUGH; - case CK_Cannonlake: - setFeatureEnabledImpl(Features, "avx512f", true); - setFeatureEnabledImpl(Features, "avx512cd", true); - setFeatureEnabledImpl(Features, "avx512dq", true); - setFeatureEnabledImpl(Features, "avx512bw", true); - setFeatureEnabledImpl(Features, "avx512vl", true); - setFeatureEnabledImpl(Features, "avx512ifma", true); - setFeatureEnabledImpl(Features, "avx512vbmi", true); - setFeatureEnabledImpl(Features, "pku", true); - setFeatureEnabledImpl(Features, "sha", true); - LLVM_FALLTHROUGH; - case CK_SkylakeClient: - setFeatureEnabledImpl(Features, "sgx", true); - // SkylakeServer cores inherits all SKL features, except SGX -SkylakeCommon: - setFeatureEnabledImpl(Features, "xsavec", true); - setFeatureEnabledImpl(Features, "xsaves", true); - setFeatureEnabledImpl(Features, "clflushopt", true); - setFeatureEnabledImpl(Features, "aes", true); - LLVM_FALLTHROUGH; - case CK_Broadwell: - setFeatureEnabledImpl(Features, "rdseed", true); - setFeatureEnabledImpl(Features, "adx", true); - setFeatureEnabledImpl(Features, "prfchw", true); - LLVM_FALLTHROUGH; - case CK_Haswell: - setFeatureEnabledImpl(Features, "avx2", true); - setFeatureEnabledImpl(Features, "lzcnt", true); - setFeatureEnabledImpl(Features, "bmi", true); - setFeatureEnabledImpl(Features, "bmi2", true); - setFeatureEnabledImpl(Features, "fma", true); - setFeatureEnabledImpl(Features, "invpcid", true); - setFeatureEnabledImpl(Features, "movbe", true); - LLVM_FALLTHROUGH; - case CK_IvyBridge: - setFeatureEnabledImpl(Features, "rdrnd", true); - setFeatureEnabledImpl(Features, "f16c", true); - setFeatureEnabledImpl(Features, "fsgsbase", true); - LLVM_FALLTHROUGH; - case CK_SandyBridge: - setFeatureEnabledImpl(Features, "avx", true); - setFeatureEnabledImpl(Features, "xsave", true); - setFeatureEnabledImpl(Features, "xsaveopt", true); - LLVM_FALLTHROUGH; - case CK_Westmere: - setFeatureEnabledImpl(Features, "pclmul", true); - LLVM_FALLTHROUGH; - case CK_Nehalem: - setFeatureEnabledImpl(Features, "sse4.2", true); - LLVM_FALLTHROUGH; - case CK_Penryn: - setFeatureEnabledImpl(Features, "sse4.1", true); - LLVM_FALLTHROUGH; - case CK_Core2: - setFeatureEnabledImpl(Features, "ssse3", true); - setFeatureEnabledImpl(Features, "sahf", true); - LLVM_FALLTHROUGH; - case CK_Nocona: - setFeatureEnabledImpl(Features, "cx16", true); - LLVM_FALLTHROUGH; - case CK_Yonah: - case CK_Prescott: - setFeatureEnabledImpl(Features, "sse3", true); - LLVM_FALLTHROUGH; - case CK_PentiumM: - case CK_Pentium4: - case CK_x86_64: - setFeatureEnabledImpl(Features, "sse2", true); - LLVM_FALLTHROUGH; - case CK_Pentium3: - case CK_C3_2: - setFeatureEnabledImpl(Features, "sse", true); - LLVM_FALLTHROUGH; - case CK_Pentium2: - setFeatureEnabledImpl(Features, "fxsr", true); - LLVM_FALLTHROUGH; - case CK_PentiumMMX: - case CK_K6: - case CK_WinChipC6: - setFeatureEnabledImpl(Features, "mmx", true); - break; - - case CK_Tremont: - setFeatureEnabledImpl(Features, "cldemote", true); - setFeatureEnabledImpl(Features, "movdiri", true); - setFeatureEnabledImpl(Features, "movdir64b", true); - setFeatureEnabledImpl(Features, "gfni", true); - setFeatureEnabledImpl(Features, "waitpkg", true); - LLVM_FALLTHROUGH; - case CK_GoldmontPlus: - setFeatureEnabledImpl(Features, "ptwrite", true); - setFeatureEnabledImpl(Features, "rdpid", true); - setFeatureEnabledImpl(Features, "sgx", true); - LLVM_FALLTHROUGH; - case CK_Goldmont: - setFeatureEnabledImpl(Features, "sha", true); - setFeatureEnabledImpl(Features, "rdseed", true); - setFeatureEnabledImpl(Features, "xsave", true); - setFeatureEnabledImpl(Features, "xsaveopt", true); - setFeatureEnabledImpl(Features, "xsavec", true); - setFeatureEnabledImpl(Features, "xsaves", true); - setFeatureEnabledImpl(Features, "clflushopt", true); - setFeatureEnabledImpl(Features, "fsgsbase", true); - setFeatureEnabledImpl(Features, "aes", true); - LLVM_FALLTHROUGH; - case CK_Silvermont: - setFeatureEnabledImpl(Features, "rdrnd", true); - setFeatureEnabledImpl(Features, "pclmul", true); - setFeatureEnabledImpl(Features, "sse4.2", true); - setFeatureEnabledImpl(Features, "prfchw", true); - LLVM_FALLTHROUGH; - case CK_Bonnell: - setFeatureEnabledImpl(Features, "movbe", true); - setFeatureEnabledImpl(Features, "ssse3", true); - setFeatureEnabledImpl(Features, "fxsr", true); - setFeatureEnabledImpl(Features, "cx16", true); - setFeatureEnabledImpl(Features, "sahf", true); - setFeatureEnabledImpl(Features, "mmx", true); - break; - - case CK_KNM: - // TODO: Add avx5124fmaps/avx5124vnniw. - setFeatureEnabledImpl(Features, "avx512vpopcntdq", true); - LLVM_FALLTHROUGH; - case CK_KNL: - setFeatureEnabledImpl(Features, "avx512f", true); - setFeatureEnabledImpl(Features, "avx512cd", true); - setFeatureEnabledImpl(Features, "avx512er", true); - setFeatureEnabledImpl(Features, "avx512pf", true); - setFeatureEnabledImpl(Features, "prfchw", true); - setFeatureEnabledImpl(Features, "prefetchwt1", true); - setFeatureEnabledImpl(Features, "fxsr", true); - setFeatureEnabledImpl(Features, "rdseed", true); - setFeatureEnabledImpl(Features, "adx", true); - setFeatureEnabledImpl(Features, "lzcnt", true); - setFeatureEnabledImpl(Features, "bmi", true); - setFeatureEnabledImpl(Features, "bmi2", true); - setFeatureEnabledImpl(Features, "fma", true); - setFeatureEnabledImpl(Features, "rdrnd", true); - setFeatureEnabledImpl(Features, "f16c", true); - setFeatureEnabledImpl(Features, "fsgsbase", true); - setFeatureEnabledImpl(Features, "aes", true); - setFeatureEnabledImpl(Features, "pclmul", true); - setFeatureEnabledImpl(Features, "cx16", true); - setFeatureEnabledImpl(Features, "xsaveopt", true); - setFeatureEnabledImpl(Features, "xsave", true); - setFeatureEnabledImpl(Features, "movbe", true); - setFeatureEnabledImpl(Features, "sahf", true); - setFeatureEnabledImpl(Features, "mmx", true); - break; - - case CK_K6_2: - case CK_K6_3: - case CK_WinChip2: - case CK_C3: - setFeatureEnabledImpl(Features, "3dnow", true); - break; - - case CK_AMDFAM10: - setFeatureEnabledImpl(Features, "sse4a", true); - setFeatureEnabledImpl(Features, "lzcnt", true); - setFeatureEnabledImpl(Features, "popcnt", true); - setFeatureEnabledImpl(Features, "sahf", true); - LLVM_FALLTHROUGH; - case CK_K8SSE3: - setFeatureEnabledImpl(Features, "sse3", true); - LLVM_FALLTHROUGH; - case CK_K8: - setFeatureEnabledImpl(Features, "sse2", true); - LLVM_FALLTHROUGH; - case CK_AthlonXP: - setFeatureEnabledImpl(Features, "sse", true); - setFeatureEnabledImpl(Features, "fxsr", true); - LLVM_FALLTHROUGH; - case CK_Athlon: - case CK_Geode: - setFeatureEnabledImpl(Features, "3dnowa", true); - break; - - case CK_BTVER2: - setFeatureEnabledImpl(Features, "avx", true); - setFeatureEnabledImpl(Features, "aes", true); - setFeatureEnabledImpl(Features, "pclmul", true); - setFeatureEnabledImpl(Features, "bmi", true); - setFeatureEnabledImpl(Features, "f16c", true); - setFeatureEnabledImpl(Features, "xsaveopt", true); - setFeatureEnabledImpl(Features, "movbe", true); - LLVM_FALLTHROUGH; - case CK_BTVER1: - setFeatureEnabledImpl(Features, "ssse3", true); - setFeatureEnabledImpl(Features, "sse4a", true); - setFeatureEnabledImpl(Features, "lzcnt", true); - setFeatureEnabledImpl(Features, "popcnt", true); - setFeatureEnabledImpl(Features, "prfchw", true); - setFeatureEnabledImpl(Features, "cx16", true); - setFeatureEnabledImpl(Features, "fxsr", true); - setFeatureEnabledImpl(Features, "sahf", true); - setFeatureEnabledImpl(Features, "mmx", true); - break; - - case CK_ZNVER2: - setFeatureEnabledImpl(Features, "clwb", true); - setFeatureEnabledImpl(Features, "rdpid", true); - setFeatureEnabledImpl(Features, "wbnoinvd", true); - LLVM_FALLTHROUGH; - case CK_ZNVER1: - setFeatureEnabledImpl(Features, "adx", true); - setFeatureEnabledImpl(Features, "aes", true); - setFeatureEnabledImpl(Features, "avx2", true); - setFeatureEnabledImpl(Features, "bmi", true); - setFeatureEnabledImpl(Features, "bmi2", true); - setFeatureEnabledImpl(Features, "clflushopt", true); - setFeatureEnabledImpl(Features, "clzero", true); - setFeatureEnabledImpl(Features, "cx16", true); - setFeatureEnabledImpl(Features, "f16c", true); - setFeatureEnabledImpl(Features, "fma", true); - setFeatureEnabledImpl(Features, "fsgsbase", true); - setFeatureEnabledImpl(Features, "fxsr", true); - setFeatureEnabledImpl(Features, "lzcnt", true); - setFeatureEnabledImpl(Features, "mmx", true); - setFeatureEnabledImpl(Features, "mwaitx", true); - setFeatureEnabledImpl(Features, "movbe", true); - setFeatureEnabledImpl(Features, "pclmul", true); - setFeatureEnabledImpl(Features, "popcnt", true); - setFeatureEnabledImpl(Features, "prfchw", true); - setFeatureEnabledImpl(Features, "rdrnd", true); - setFeatureEnabledImpl(Features, "rdseed", true); - setFeatureEnabledImpl(Features, "sahf", true); - setFeatureEnabledImpl(Features, "sha", true); - setFeatureEnabledImpl(Features, "sse4a", true); - setFeatureEnabledImpl(Features, "xsave", true); - setFeatureEnabledImpl(Features, "xsavec", true); - setFeatureEnabledImpl(Features, "xsaveopt", true); - setFeatureEnabledImpl(Features, "xsaves", true); - break; - - case CK_BDVER4: - setFeatureEnabledImpl(Features, "avx2", true); - setFeatureEnabledImpl(Features, "bmi2", true); - setFeatureEnabledImpl(Features, "mwaitx", true); - LLVM_FALLTHROUGH; - case CK_BDVER3: - setFeatureEnabledImpl(Features, "fsgsbase", true); - setFeatureEnabledImpl(Features, "xsaveopt", true); - LLVM_FALLTHROUGH; - case CK_BDVER2: - setFeatureEnabledImpl(Features, "bmi", true); - setFeatureEnabledImpl(Features, "fma", true); - setFeatureEnabledImpl(Features, "f16c", true); - setFeatureEnabledImpl(Features, "tbm", true); - LLVM_FALLTHROUGH; - case CK_BDVER1: - // xop implies avx, sse4a and fma4. - setFeatureEnabledImpl(Features, "xop", true); - setFeatureEnabledImpl(Features, "lwp", true); - setFeatureEnabledImpl(Features, "lzcnt", true); - setFeatureEnabledImpl(Features, "aes", true); - setFeatureEnabledImpl(Features, "pclmul", true); - setFeatureEnabledImpl(Features, "prfchw", true); - setFeatureEnabledImpl(Features, "cx16", true); - setFeatureEnabledImpl(Features, "fxsr", true); - setFeatureEnabledImpl(Features, "xsave", true); - setFeatureEnabledImpl(Features, "sahf", true); - setFeatureEnabledImpl(Features, "mmx", true); - break; - } if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec)) return false; @@ -452,12 +129,6 @@ SkylakeCommon: llvm::find(FeaturesVec, "-popcnt") == FeaturesVec.end()) Features["popcnt"] = true; - // Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled. - I = Features.find("3dnow"); - if (I != Features.end() && I->getValue() && - llvm::find(FeaturesVec, "-prfchw") == FeaturesVec.end()) - Features["prfchw"] = true; - // Additionally, if SSE is enabled and mmx is not explicitly disabled, // then enable MMX. I = Features.find("sse"); @@ -465,264 +136,34 @@ SkylakeCommon: llvm::find(FeaturesVec, "-mmx") == FeaturesVec.end()) Features["mmx"] = true; - return true; -} - -void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features, - X86SSEEnum Level, bool Enabled) { - if (Enabled) { - switch (Level) { - case AVX512F: - Features["avx512f"] = true; - Features["fma"] = true; - Features["f16c"] = true; - LLVM_FALLTHROUGH; - case AVX2: - Features["avx2"] = true; - LLVM_FALLTHROUGH; - case AVX: - Features["avx"] = true; - Features["xsave"] = true; - LLVM_FALLTHROUGH; - case SSE42: - Features["sse4.2"] = true; - LLVM_FALLTHROUGH; - case SSE41: - Features["sse4.1"] = true; - LLVM_FALLTHROUGH; - case SSSE3: - Features["ssse3"] = true; - LLVM_FALLTHROUGH; - case SSE3: - Features["sse3"] = true; - LLVM_FALLTHROUGH; - case SSE2: - Features["sse2"] = true; - LLVM_FALLTHROUGH; - case SSE1: - Features["sse"] = true; - LLVM_FALLTHROUGH; - case NoSSE: - break; - } - return; - } - - switch (Level) { - case NoSSE: - case SSE1: - Features["sse"] = false; - LLVM_FALLTHROUGH; - case SSE2: - Features["sse2"] = Features["pclmul"] = Features["aes"] = false; - Features["sha"] = Features["gfni"] = false; - LLVM_FALLTHROUGH; - case SSE3: - Features["sse3"] = false; - setXOPLevel(Features, NoXOP, false); - LLVM_FALLTHROUGH; - case SSSE3: - Features["ssse3"] = false; - LLVM_FALLTHROUGH; - case SSE41: - Features["sse4.1"] = false; - LLVM_FALLTHROUGH; - case SSE42: - Features["sse4.2"] = false; - LLVM_FALLTHROUGH; - case AVX: - Features["fma"] = Features["avx"] = Features["f16c"] = false; - Features["xsave"] = Features["xsaveopt"] = Features["vaes"] = false; - Features["vpclmulqdq"] = false; - setXOPLevel(Features, FMA4, false); - LLVM_FALLTHROUGH; - case AVX2: - Features["avx2"] = false; - LLVM_FALLTHROUGH; - case AVX512F: - Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] = false; - Features["avx512pf"] = Features["avx512dq"] = Features["avx512bw"] = false; - Features["avx512vl"] = Features["avx512vbmi"] = false; - Features["avx512ifma"] = Features["avx512vpopcntdq"] = false; - Features["avx512bitalg"] = Features["avx512vnni"] = false; - Features["avx512vbmi2"] = Features["avx512bf16"] = false; - Features["avx512vp2intersect"] = false; - break; - } -} - -void X86TargetInfo::setMMXLevel(llvm::StringMap<bool> &Features, - MMX3DNowEnum Level, bool Enabled) { - if (Enabled) { - switch (Level) { - case AMD3DNowAthlon: - Features["3dnowa"] = true; - LLVM_FALLTHROUGH; - case AMD3DNow: - Features["3dnow"] = true; - LLVM_FALLTHROUGH; - case MMX: - Features["mmx"] = true; - LLVM_FALLTHROUGH; - case NoMMX3DNow: - break; - } - return; - } - - switch (Level) { - case NoMMX3DNow: - case MMX: - Features["mmx"] = false; - LLVM_FALLTHROUGH; - case AMD3DNow: - Features["3dnow"] = false; - LLVM_FALLTHROUGH; - case AMD3DNowAthlon: - Features["3dnowa"] = false; - break; - } -} - -void X86TargetInfo::setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level, - bool Enabled) { - if (Enabled) { - switch (Level) { - case XOP: - Features["xop"] = true; - LLVM_FALLTHROUGH; - case FMA4: - Features["fma4"] = true; - setSSELevel(Features, AVX, true); - LLVM_FALLTHROUGH; - case SSE4A: - Features["sse4a"] = true; - setSSELevel(Features, SSE3, true); - LLVM_FALLTHROUGH; - case NoXOP: - break; - } - return; - } + // Enable xsave if avx is enabled and xsave is not explicitly disabled. + I = Features.find("avx"); + if (I != Features.end() && I->getValue() && + llvm::find(FeaturesVec, "-xsave") == FeaturesVec.end()) + Features["xsave"] = true; - switch (Level) { - case NoXOP: - case SSE4A: - Features["sse4a"] = false; - LLVM_FALLTHROUGH; - case FMA4: - Features["fma4"] = false; - LLVM_FALLTHROUGH; - case XOP: - Features["xop"] = false; - break; - } + return true; } -void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features, - StringRef Name, bool Enabled) { - // This is a bit of a hack to deal with the sse4 target feature when used - // as part of the target attribute. We handle sse4 correctly everywhere - // else. See below for more information on how we handle the sse4 options. - if (Name != "sse4") - Features[Name] = Enabled; - - if (Name == "mmx") { - setMMXLevel(Features, MMX, Enabled); - } else if (Name == "sse") { - setSSELevel(Features, SSE1, Enabled); - } else if (Name == "sse2") { - setSSELevel(Features, SSE2, Enabled); - } else if (Name == "sse3") { - setSSELevel(Features, SSE3, Enabled); - } else if (Name == "ssse3") { - setSSELevel(Features, SSSE3, Enabled); - } else if (Name == "sse4.2") { - setSSELevel(Features, SSE42, Enabled); - } else if (Name == "sse4.1") { - setSSELevel(Features, SSE41, Enabled); - } else if (Name == "3dnow") { - setMMXLevel(Features, AMD3DNow, Enabled); - } else if (Name == "3dnowa") { - setMMXLevel(Features, AMD3DNowAthlon, Enabled); - } else if (Name == "aes") { - if (Enabled) - setSSELevel(Features, SSE2, Enabled); - else - Features["vaes"] = false; - } else if (Name == "vaes") { - if (Enabled) { - setSSELevel(Features, AVX, Enabled); - Features["aes"] = true; - } - } else if (Name == "pclmul") { - if (Enabled) - setSSELevel(Features, SSE2, Enabled); - else - Features["vpclmulqdq"] = false; - } else if (Name == "vpclmulqdq") { - if (Enabled) { - setSSELevel(Features, AVX, Enabled); - Features["pclmul"] = true; - } - } else if (Name == "gfni") { - if (Enabled) - setSSELevel(Features, SSE2, Enabled); - } else if (Name == "avx") { - setSSELevel(Features, AVX, Enabled); - } else if (Name == "avx2") { - setSSELevel(Features, AVX2, Enabled); - } else if (Name == "avx512f") { - setSSELevel(Features, AVX512F, Enabled); - } else if (Name.startswith("avx512")) { - if (Enabled) - setSSELevel(Features, AVX512F, Enabled); - // Enable BWI instruction if certain features are being enabled. - if ((Name == "avx512vbmi" || Name == "avx512vbmi2" || - Name == "avx512bitalg" || Name == "avx512bf16") && Enabled) - Features["avx512bw"] = true; - // Also disable some features if BWI is being disabled. - if (Name == "avx512bw" && !Enabled) { - Features["avx512vbmi"] = false; - Features["avx512vbmi2"] = false; - Features["avx512bitalg"] = false; - Features["avx512bf16"] = false; - } - } else if (Name == "fma") { - if (Enabled) - setSSELevel(Features, AVX, Enabled); - else - setSSELevel(Features, AVX512F, Enabled); - } else if (Name == "fma4") { - setXOPLevel(Features, FMA4, Enabled); - } else if (Name == "xop") { - setXOPLevel(Features, XOP, Enabled); - } else if (Name == "sse4a") { - setXOPLevel(Features, SSE4A, Enabled); - } else if (Name == "f16c") { - if (Enabled) - setSSELevel(Features, AVX, Enabled); - else - setSSELevel(Features, AVX512F, Enabled); - } else if (Name == "sha") { - if (Enabled) - setSSELevel(Features, SSE2, Enabled); - } else if (Name == "sse4") { +void X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, + StringRef Name, bool Enabled) const { + if (Name == "sse4") { // We can get here via the __target__ attribute since that's not controlled // via the -msse4/-mno-sse4 command line alias. Handle this the same way // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if // disabled. if (Enabled) - setSSELevel(Features, SSE42, Enabled); + Name = "sse4.2"; else - setSSELevel(Features, SSE41, Enabled); - } else if (Name == "xsave") { - if (!Enabled) - Features["xsaveopt"] = false; - } else if (Name == "xsaveopt" || Name == "xsavec" || Name == "xsaves") { - if (Enabled) - Features["xsave"] = true; + Name = "sse4.1"; } + + Features[Name] = Enabled; + + SmallVector<StringRef, 8> ImpliedFeatures; + llvm::X86::getImpliedFeatures(Name, Enabled, ImpliedFeatures); + for (const auto &F : ImpliedFeatures) + Features[F] = Enabled; } /// handleTargetFeatures - Perform initialization based on the user @@ -857,6 +298,16 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasINVPCID = true; } else if (Feature == "+enqcmd") { HasENQCMD = true; + } else if (Feature == "+amx-bf16") { + HasAMXBF16 = true; + } else if (Feature == "+amx-int8") { + HasAMXINT8 = true; + } else if (Feature == "+amx-tile") { + HasAMXTILE = true; + } else if (Feature == "+serialize") { + HasSERIALIZE = true; + } else if (Feature == "+tsxldtrk") { + HasTSXLDTRK = true; } X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) @@ -911,7 +362,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, std::string CodeModel = getTargetOpts().CodeModel; if (CodeModel == "default") CodeModel = "small"; - Builder.defineMacro("__code_model_" + CodeModel + "_"); + Builder.defineMacro("__code_model_" + CodeModel + "__"); // Target identification. if (getTriple().getArch() == llvm::Triple::x86_64) { @@ -935,8 +386,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. @@ -1247,6 +699,16 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__INVPCID__"); if (HasENQCMD) Builder.defineMacro("__ENQCMD__"); + if (HasAMXTILE) + Builder.defineMacro("__AMXTILE__"); + if (HasAMXINT8) + Builder.defineMacro("__AMXINT8__"); + if (HasAMXBF16) + Builder.defineMacro("__AMXBF16__"); + if (HasSERIALIZE) + Builder.defineMacro("__SERIALIZE__"); + if (HasTSXLDTRK) + Builder.defineMacro("__TSXLDTRK__"); // Each case falls through to the previous one here. switch (SSELevel) { @@ -1319,7 +781,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"); @@ -1339,6 +801,9 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("3dnowa", true) .Case("adx", true) .Case("aes", true) + .Case("amx-bf16", true) + .Case("amx-int8", true) + .Case("amx-tile", true) .Case("avx", true) .Case("avx2", true) .Case("avx512f", true) @@ -1390,6 +855,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("rdseed", true) .Case("rtm", true) .Case("sahf", true) + .Case("serialize", true) .Case("sgx", true) .Case("sha", true) .Case("shstk", true) @@ -1402,6 +868,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("sse4.2", true) .Case("sse4a", true) .Case("tbm", true) + .Case("tsxldtrk", true) .Case("vaes", true) .Case("vpclmulqdq", true) .Case("wbnoinvd", true) @@ -1419,6 +886,9 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch<bool>(Feature) .Case("adx", HasADX) .Case("aes", HasAES) + .Case("amx-bf16", HasAMXBF16) + .Case("amx-int8", HasAMXINT8) + .Case("amx-tile", HasAMXTILE) .Case("avx", SSELevel >= AVX) .Case("avx2", SSELevel >= AVX2) .Case("avx512f", SSELevel >= AVX512F) @@ -1474,6 +944,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("retpoline-external-thunk", HasRetpolineExternalThunk) .Case("rtm", HasRTM) .Case("sahf", HasLAHFSAHF) + .Case("serialize", HasSERIALIZE) .Case("sgx", HasSGX) .Case("sha", HasSHA) .Case("shstk", HasSHSTK) @@ -1485,6 +956,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("sse4.2", SSELevel >= SSE42) .Case("sse4a", XOPLevel >= SSE4A) .Case("tbm", HasTBM) + .Case("tsxldtrk", HasTSXLDTRK) .Case("vaes", HasVAES) .Case("vpclmulqdq", HasVPCLMULQDQ) .Case("wbnoinvd", HasWBNOINVD) @@ -1507,14 +979,14 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { // X86TargetInfo::hasFeature for a somewhat comprehensive list). bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const { return llvm::StringSwitch<bool>(FeatureStr) -#define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, true) +#define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, true) #include "llvm/Support/X86TargetParser.def" .Default(false); } static llvm::X86::ProcessorFeatures getFeature(StringRef Name) { return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name) -#define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, llvm::X86::ENUM) +#define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, llvm::X86::FEATURE_##ENUM) #include "llvm/Support/X86TargetParser.def" ; // Note, this function should only be used after ensuring the value is @@ -1539,17 +1011,11 @@ 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) { - 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" - } + using namespace llvm::X86; + CPUKind Kind = parseArchX86(Name); + if (Kind != CK_None) { + ProcessorFeatures KeyFeature = getKeyFeature(Kind); + return (getFeaturePriority(KeyFeature) << 1) + 1; } // Now we know we have a feature, so get its priority and shift it a few so @@ -1596,10 +1062,9 @@ void X86TargetInfo::getCPUSpecificCPUDispatchFeatures( bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const { return llvm::StringSwitch<bool>(FeatureStr) #define X86_VENDOR(ENUM, STRING) .Case(STRING, true) -#define X86_CPU_TYPE_COMPAT_WITH_ALIAS(ARCHNAME, ENUM, STR, ALIAS) \ - .Cases(STR, ALIAS, true) -#define X86_CPU_TYPE_COMPAT(ARCHNAME, ENUM, STR) .Case(STR, true) -#define X86_CPU_SUBTYPE_COMPAT(ARCHNAME, ENUM, STR) .Case(STR, true) +#define X86_CPU_TYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true) +#define X86_CPU_TYPE(ENUM, STR) .Case(STR, true) +#define X86_CPU_SUBTYPE(ENUM, STR) .Case(STR, true) #include "llvm/Support/X86TargetParser.def" .Default(false); } @@ -1679,8 +1144,7 @@ bool X86TargetInfo::validateAsmConstraint( switch (*Name) { default: return false; - case 'z': - case '0': // First SSE register. + case 'z': // First SSE register. case '2': case 't': // Any SSE register, when SSE2 is enabled. case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled. @@ -1731,6 +1195,121 @@ bool X86TargetInfo::validateAsmConstraint( } } +// Below is based on the following information: +// +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +// | Processor Name | Cache Line Size (Bytes) | Source | +// +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +// | i386 | 64 | https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf | +// | i486 | 16 | "four doublewords" (doubleword = 32 bits, 4 bits * 32 bits = 16 bytes) https://en.wikichip.org/w/images/d/d3/i486_MICROPROCESSOR_HARDWARE_REFERENCE_MANUAL_%281990%29.pdf and http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.126.4216&rep=rep1&type=pdf (page 29) | +// | i586/Pentium MMX | 32 | https://www.7-cpu.com/cpu/P-MMX.html | +// | i686/Pentium | 32 | https://www.7-cpu.com/cpu/P6.html | +// | Netburst/Pentium4 | 64 | https://www.7-cpu.com/cpu/P4-180.html | +// | Atom | 64 | https://www.7-cpu.com/cpu/Atom.html | +// | Westmere | 64 | https://en.wikichip.org/wiki/intel/microarchitectures/sandy_bridge_(client) "Cache Architecture" | +// | Sandy Bridge | 64 | https://en.wikipedia.org/wiki/Sandy_Bridge and https://www.7-cpu.com/cpu/SandyBridge.html | +// | Ivy Bridge | 64 | https://blog.stuffedcow.net/2013/01/ivb-cache-replacement/ and https://www.7-cpu.com/cpu/IvyBridge.html | +// | Haswell | 64 | https://www.7-cpu.com/cpu/Haswell.html | +// | Boadwell | 64 | https://www.7-cpu.com/cpu/Broadwell.html | +// | Skylake (including skylake-avx512) | 64 | https://www.nas.nasa.gov/hecc/support/kb/skylake-processors_550.html "Cache Hierarchy" | +// | Cascade Lake | 64 | https://www.nas.nasa.gov/hecc/support/kb/cascade-lake-processors_579.html "Cache Hierarchy" | +// | Skylake | 64 | https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake "Memory Hierarchy" | +// | Ice Lake | 64 | https://www.7-cpu.com/cpu/Ice_Lake.html | +// | Knights Landing | 64 | https://software.intel.com/en-us/articles/intel-xeon-phi-processor-7200-family-memory-management-optimizations "The Intel® Xeon Phi™ Processor Architecture" | +// | 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: + // i486 + case CK_i486: + case CK_WinChipC6: + case CK_WinChip2: + case CK_C3: + // Lakemont + case CK_Lakemont: + return 16; + + // i586 + case CK_i586: + case CK_Pentium: + case CK_PentiumMMX: + // i686 + case CK_PentiumPro: + case CK_i686: + case CK_Pentium2: + case CK_Pentium3: + case CK_PentiumM: + case CK_C3_2: + // K6 + case CK_K6: + case CK_K6_2: + case CK_K6_3: + // Geode + case CK_Geode: + return 32; + + // Netburst + case CK_Pentium4: + case CK_Prescott: + case CK_Nocona: + // Atom + case CK_Bonnell: + case CK_Silvermont: + case CK_Goldmont: + case CK_GoldmontPlus: + case CK_Tremont: + + case CK_Westmere: + case CK_SandyBridge: + case CK_IvyBridge: + case CK_Haswell: + case CK_Broadwell: + case CK_SkylakeClient: + case CK_SkylakeServer: + case CK_Cascadelake: + case CK_Nehalem: + case CK_Cooperlake: + case CK_Cannonlake: + case CK_Tigerlake: + case CK_IcelakeClient: + case CK_IcelakeServer: + case CK_KNL: + case CK_KNM: + // K7 + case CK_Athlon: + case CK_AthlonXP: + // K8 + case CK_K8: + case CK_K8SSE3: + case CK_AMDFAM10: + // Bobcat + case CK_BTVER1: + case CK_BTVER2: + // Bulldozer + case CK_BDVER1: + case CK_BDVER2: + case CK_BDVER3: + case CK_BDVER4: + // Zen + case CK_ZNVER1: + case CK_ZNVER2: + // Deprecated + case CK_x86_64: + case CK_Yonah: + case CK_Penryn: + case CK_Core2: + return 64; + + // The following currently have unknown cache line sizes (but they are probably all 64): + // Core + case CK_None: + return None; + } + llvm_unreachable("Unknown CPU kind"); +} + bool X86TargetInfo::validateOutputSize(const llvm::StringMap<bool> &FeatureMap, StringRef Constraint, unsigned Size) const { @@ -1771,9 +1350,14 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap, case 'k': return Size <= 64; case 'z': - case '0': - // XMM0 - if (FeatureMap.lookup("sse")) + // XMM0/YMM/ZMM0 + if (FeatureMap.lookup("avx512f")) + // ZMM0 can be used if target supports AVX512F. + return Size <= 512U; + else if (FeatureMap.lookup("avx")) + // YMM0 can be used if target supports AVX. + return Size <= 256U; + else if (FeatureMap.lookup("sse")) return Size <= 128U; return false; case 'i': @@ -1784,7 +1368,7 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap, return false; break; } - LLVM_FALLTHROUGH; + break; case 'v': case 'x': if (FeatureMap.lookup("avx512f")) @@ -1839,7 +1423,6 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const { case 'i': case 't': case 'z': - case '0': case '2': // "^" hints llvm that this is a 2 letter constraint. // "Constraint++" is used to promote the string iterator @@ -1852,38 +1435,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 { diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 5b5e284e5141..72a01d2514c2 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -18,6 +18,7 @@ #include "clang/Basic/TargetOptions.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/X86TargetParser.h" namespace clang { namespace targets { @@ -124,21 +125,14 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasPTWRITE = false; bool HasINVPCID = false; bool HasENQCMD = false; + bool HasAMXTILE = false; + bool HasAMXINT8 = false; + bool HasAMXBF16 = false; + bool HasSERIALIZE = false; + bool HasTSXLDTRK = false; protected: - /// Enumeration of all of the X86 CPUs supported by Clang. - /// - /// Each enumeration represents a particular CPU supported by Clang. These - /// loosely correspond to the options passed to '-march' or '-mtune' flags. - enum CPUKind { - CK_Generic, -#define PROC(ENUM, STRING, IS64BIT) CK_##ENUM, -#include "clang/Basic/X86Target.def" - } CPU = CK_Generic; - - bool checkCPUKind(CPUKind Kind) const; - - CPUKind getCPUKind(StringRef CPU) const; + llvm::X86::CPUKind CPU = llvm::X86::CK_None; enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default; @@ -147,6 +141,7 @@ public: : TargetInfo(Triple) { LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); AddrSpaceMap = &X86AddrSpaceMap; + HasStrictFP = true; } const char *getLongDoubleMangling() const override { @@ -166,6 +161,10 @@ public: ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; + bool isSPRegName(StringRef RegName) const override { + return RegName.equals("esp") || RegName.equals("rsp"); + } + bool validateCpuSupports(StringRef Name) const override; bool validateCpuIs(StringRef Name) const override; @@ -178,6 +177,8 @@ public: StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const override; + Optional<unsigned> getCPUCacheLineSize() const override; + bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override; @@ -262,24 +263,8 @@ public: void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level, - bool Enabled); - - static void setMMXLevel(llvm::StringMap<bool> &Features, MMX3DNowEnum Level, - bool Enabled); - - static void setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level, - bool Enabled); - void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, - bool Enabled) const override { - setFeatureEnabledImpl(Features, Name, Enabled); - } - - // This exists purely to cut down on the number of virtual calls in - // initFeatureMap which calls this repeatedly. - static void setFeatureEnabledImpl(llvm::StringMap<bool> &Features, - StringRef Name, bool Enabled); + bool Enabled) const final; bool initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, @@ -288,7 +273,7 @@ public: bool isValidFeatureName(StringRef Name) const override; - bool hasFeature(StringRef Feature) const override; + bool hasFeature(StringRef Feature) const final; bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override; @@ -305,13 +290,16 @@ public: } bool isValidCPUName(StringRef Name) const override { - return checkCPUKind(getCPUKind(Name)); + bool Only64Bit = getTriple().getArch() != llvm::Triple::x86; + return llvm::X86::parseArchX86(Name, Only64Bit) != llvm::X86::CK_None; } void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; bool setCPU(const std::string &Name) override { - return checkCPUKind(CPU = getCPUKind(Name)); + bool Only64Bit = getTriple().getArch() != llvm::Triple::x86; + CPU = llvm::X86::parseArchX86(Name, Only64Bit); + return CPU != llvm::X86::CK_None; } unsigned multiVersionSortPriority(StringRef Name) const override; @@ -427,6 +415,8 @@ public: } ArrayRef<Builtin::Info> getTargetBuiltins() const override; + + bool hasExtIntType() const override { return true; } }; class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo @@ -729,6 +719,8 @@ public: } ArrayRef<Builtin::Info> getTargetBuiltins() const override; + + bool hasExtIntType() const override { return true; } }; // x86-64 Windows target diff --git a/clang/lib/Basic/Targets/XCore.h b/clang/lib/Basic/Targets/XCore.h index c94f93a99bca..c33766751aa1 100644 --- a/clang/lib/Basic/Targets/XCore.h +++ b/clang/lib/Basic/Targets/XCore.h @@ -75,6 +75,8 @@ public: } bool allowsLargerPreferedTypeAlignment() const override { return false; } + + bool hasExtIntType() const override { return true; } }; } // namespace targets } // namespace clang diff --git a/clang/lib/Basic/TypeTraits.cpp b/clang/lib/Basic/TypeTraits.cpp new file mode 100644 index 000000000000..3b723afff70b --- /dev/null +++ b/clang/lib/Basic/TypeTraits.cpp @@ -0,0 +1,86 @@ +//===--- TypeTraits.cpp - Type Traits Support -----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the type traits support functions. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/TypeTraits.h" +#include "llvm/Support/ErrorHandling.h" +#include <cassert> +using namespace clang; + +static constexpr const char *TypeTraitNames[] = { +#define TYPE_TRAIT_1(Spelling, Name, Key) #Name, +#include "clang/Basic/TokenKinds.def" +#define TYPE_TRAIT_2(Spelling, Name, Key) #Name, +#include "clang/Basic/TokenKinds.def" +#define TYPE_TRAIT_N(Spelling, Name, Key) #Name, +#include "clang/Basic/TokenKinds.def" +}; + +static constexpr const char *TypeTraitSpellings[] = { +#define TYPE_TRAIT_1(Spelling, Name, Key) #Spelling, +#include "clang/Basic/TokenKinds.def" +#define TYPE_TRAIT_2(Spelling, Name, Key) #Spelling, +#include "clang/Basic/TokenKinds.def" +#define TYPE_TRAIT_N(Spelling, Name, Key) #Spelling, +#include "clang/Basic/TokenKinds.def" +}; + +static constexpr const char *ArrayTypeTraitNames[] = { +#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) #Name, +#include "clang/Basic/TokenKinds.def" +}; + +static constexpr const char *ArrayTypeTraitSpellings[] = { +#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) #Spelling, +#include "clang/Basic/TokenKinds.def" +}; + +static constexpr const char *UnaryExprOrTypeTraitNames[] = { +#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) #Name, +#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) #Name, +#include "clang/Basic/TokenKinds.def" +}; + +static constexpr const char *UnaryExprOrTypeTraitSpellings[] = { +#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) #Spelling, +#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) #Spelling, +#include "clang/Basic/TokenKinds.def" +}; + +const char *clang::getTraitName(TypeTrait T) { + assert(T <= TT_Last && "invalid enum value!"); + return TypeTraitNames[T]; +} + +const char *clang::getTraitName(ArrayTypeTrait T) { + assert(T <= ATT_Last && "invalid enum value!"); + return ArrayTypeTraitNames[T]; +} + +const char *clang::getTraitName(UnaryExprOrTypeTrait T) { + assert(T <= UETT_Last && "invalid enum value!"); + return UnaryExprOrTypeTraitNames[T]; +} + +const char *clang::getTraitSpelling(TypeTrait T) { + assert(T <= TT_Last && "invalid enum value!"); + return TypeTraitSpellings[T]; +} + +const char *clang::getTraitSpelling(ArrayTypeTrait T) { + assert(T <= ATT_Last && "invalid enum value!"); + return ArrayTypeTraitSpellings[T]; +} + +const char *clang::getTraitSpelling(UnaryExprOrTypeTrait T) { + assert(T <= UETT_Last && "invalid enum value!"); + return UnaryExprOrTypeTraitSpellings[T]; +} diff --git a/clang/lib/Basic/Version.cpp b/clang/lib/Basic/Version.cpp index c69d13b2f689..286107cab9d7 100644 --- a/clang/lib/Basic/Version.cpp +++ b/clang/lib/Basic/Version.cpp @@ -28,46 +28,19 @@ std::string getClangRepositoryPath() { return CLANG_REPOSITORY_STRING; #else #ifdef CLANG_REPOSITORY - StringRef URL(CLANG_REPOSITORY); + return CLANG_REPOSITORY; #else - StringRef URL(""); + return ""; #endif - - // If the CLANG_REPOSITORY is empty, try to use the SVN keyword. This helps us - // pick up a tag in an SVN export, for example. - StringRef SVNRepository("$URL$"); - if (URL.empty()) { - URL = SVNRepository.slice(SVNRepository.find(':'), - SVNRepository.find("/lib/Basic")); - } - - // Strip off version from a build from an integration branch. - URL = URL.slice(0, URL.find("/src/tools/clang")); - - // Trim path prefix off, assuming path came from standard cfe path. - size_t Start = URL.find("cfe/"); - if (Start != StringRef::npos) - URL = URL.substr(Start + 4); - - return URL; #endif } std::string getLLVMRepositoryPath() { #ifdef LLVM_REPOSITORY - StringRef URL(LLVM_REPOSITORY); + return LLVM_REPOSITORY; #else - StringRef URL(""); + return ""; #endif - - // Trim path prefix off, assuming path came from standard llvm path. - // Leave "llvm/" prefix to distinguish the following llvm revision from the - // clang revision. - size_t Start = URL.find("llvm/"); - if (Start != StringRef::npos) - URL = URL.substr(Start); - - return URL; } std::string getClangRevision() { @@ -124,8 +97,12 @@ std::string getClangToolFullVersion(StringRef ToolName) { #ifdef CLANG_VENDOR OS << CLANG_VENDOR; #endif - OS << ToolName << " version " CLANG_VERSION_STRING " " - << getClangFullRepositoryVersion(); + OS << ToolName << " version " CLANG_VERSION_STRING; + + std::string repo = getClangFullRepositoryVersion(); + if (!repo.empty()) { + OS << " " << repo; + } return OS.str(); } @@ -138,7 +115,13 @@ std::string getClangFullCPPVersion() { #ifdef CLANG_VENDOR OS << CLANG_VENDOR; #endif - OS << "Clang " CLANG_VERSION_STRING " " << getClangFullRepositoryVersion(); + OS << "Clang " CLANG_VERSION_STRING; + + std::string repo = getClangFullRepositoryVersion(); + if (!repo.empty()) { + OS << " " << repo; + } + return OS.str(); } diff --git a/clang/lib/Basic/Warnings.cpp b/clang/lib/Basic/Warnings.cpp index 88ef2eaa6589..2c909d9510d4 100644 --- a/clang/lib/Basic/Warnings.cpp +++ b/clang/lib/Basic/Warnings.cpp @@ -36,8 +36,9 @@ static void EmitUnknownDiagWarning(DiagnosticsEngine &Diags, StringRef Opt) { StringRef Suggestion = DiagnosticIDs::getNearestOption(Flavor, Opt); Diags.Report(diag::warn_unknown_diag_option) - << (Flavor == diag::Flavor::WarningOrError ? 0 : 1) << (Prefix.str() += Opt) - << !Suggestion.empty() << (Prefix.str() += Suggestion); + << (Flavor == diag::Flavor::WarningOrError ? 0 : 1) + << (Prefix.str() += std::string(Opt)) << !Suggestion.empty() + << (Prefix.str() += std::string(Suggestion)); } void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, diff --git a/clang/lib/Basic/XRayInstr.cpp b/clang/lib/Basic/XRayInstr.cpp index ef2470f67200..79052e05860e 100644 --- a/clang/lib/Basic/XRayInstr.cpp +++ b/clang/lib/Basic/XRayInstr.cpp @@ -16,13 +16,17 @@ namespace clang { XRayInstrMask parseXRayInstrValue(StringRef Value) { - XRayInstrMask ParsedKind = llvm::StringSwitch<XRayInstrMask>(Value) - .Case("all", XRayInstrKind::All) - .Case("custom", XRayInstrKind::Custom) - .Case("function", XRayInstrKind::Function) - .Case("typed", XRayInstrKind::Typed) - .Case("none", XRayInstrKind::None) - .Default(XRayInstrKind::None); + XRayInstrMask ParsedKind = + llvm::StringSwitch<XRayInstrMask>(Value) + .Case("all", XRayInstrKind::All) + .Case("custom", XRayInstrKind::Custom) + .Case("function", + XRayInstrKind::FunctionEntry | XRayInstrKind::FunctionExit) + .Case("function-entry", XRayInstrKind::FunctionEntry) + .Case("function-exit", XRayInstrKind::FunctionExit) + .Case("typed", XRayInstrKind::Typed) + .Case("none", XRayInstrKind::None) + .Default(XRayInstrKind::None); return ParsedKind; } diff --git a/clang/lib/Basic/XRayLists.cpp b/clang/lib/Basic/XRayLists.cpp index 222a28f79cc5..6d34617d4795 100644 --- a/clang/lib/Basic/XRayLists.cpp +++ b/clang/lib/Basic/XRayLists.cpp @@ -9,7 +9,11 @@ // User-provided filters for always/never XRay instrumenting certain functions. // //===----------------------------------------------------------------------===// + #include "clang/Basic/XRayLists.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/SourceManager.h" +#include "llvm/Support/SpecialCaseList.h" using namespace clang; @@ -25,6 +29,8 @@ XRayFunctionFilter::XRayFunctionFilter( AttrListPaths, SM.getFileManager().getVirtualFileSystem())), SM(SM) {} +XRayFunctionFilter::~XRayFunctionFilter() = default; + XRayFunctionFilter::ImbueAttribute XRayFunctionFilter::shouldImbueFunction(StringRef FunctionName) const { // First apply the always instrument list, than if it isn't an "always" see |