diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Basic')
90 files changed, 8004 insertions, 2952 deletions
diff --git a/contrib/llvm-project/clang/lib/Basic/Attributes.cpp b/contrib/llvm-project/clang/lib/Basic/Attributes.cpp index 62eea9c59082..44a4f1890d39 100644 --- a/contrib/llvm-project/clang/lib/Basic/Attributes.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Attributes.cpp @@ -1,16 +1,39 @@ +//===--- Attributes.cpp ---------------------------------------------------===// +// +// 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 AttributeCommonInfo interface. +// +//===----------------------------------------------------------------------===// + #include "clang/Basic/Attributes.h" #include "clang/Basic/AttrSubjectMatchRules.h" -#include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/IdentifierTable.h" -#include "llvm/ADT/StringSwitch.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/ParsedAttrInfo.h" +#include "clang/Basic/TargetInfo.h" + using namespace clang; -int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope, - const IdentifierInfo *Attr, const TargetInfo &Target, - const LangOptions &LangOpts) { +static int hasAttributeImpl(AttributeCommonInfo::Syntax Syntax, StringRef Name, + StringRef ScopeName, const TargetInfo &Target, + const LangOptions &LangOpts) { + +#include "clang/Basic/AttrHasAttributeImpl.inc" + + return 0; +} + +int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax, + const IdentifierInfo *Scope, const IdentifierInfo *Attr, + const TargetInfo &Target, const LangOptions &LangOpts) { StringRef Name = Attr->getName(); // Normalize the attribute name, __foo__ becomes foo. - if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__")) + if (Name.size() >= 4 && Name.starts_with("__") && Name.ends_with("__")) Name = Name.substr(2, Name.size() - 4); // Normalize the scope name, but only for gnu and clang attributes. @@ -24,11 +47,17 @@ int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope, // attributes. We support those, but not through the typical attribute // machinery that goes through TableGen. We support this in all OpenMP modes // so long as double square brackets are enabled. - if (LangOpts.OpenMP && LangOpts.DoubleSquareBracketAttributes && - ScopeName == "omp") + if (LangOpts.OpenMP && ScopeName == "omp") return (Name == "directive" || Name == "sequence") ? 1 : 0; -#include "clang/Basic/AttrHasAttributeImpl.inc" + int res = hasAttributeImpl(Syntax, Name, ScopeName, Target, LangOpts); + if (res) + return res; + + // Check if any plugin provides this attribute. + for (auto &Ptr : getAttributePluginInstances()) + if (Ptr->hasSpelling(Syntax, Name)) + return 1; return 0; } @@ -53,7 +82,7 @@ normalizeAttrScopeName(const IdentifierInfo *Scope, // to be "clang". StringRef ScopeName = Scope->getName(); if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 || - SyntaxUsed == AttributeCommonInfo::AS_C2x) { + SyntaxUsed == AttributeCommonInfo::AS_C23) { if (ScopeName == "__gnu__") ScopeName = "gnu"; else if (ScopeName == "_Clang") @@ -70,12 +99,12 @@ static StringRef normalizeAttrName(const IdentifierInfo *Name, bool ShouldNormalize = SyntaxUsed == AttributeCommonInfo::AS_GNU || ((SyntaxUsed == AttributeCommonInfo::AS_CXX11 || - SyntaxUsed == AttributeCommonInfo::AS_C2x) && + SyntaxUsed == AttributeCommonInfo::AS_C23) && (NormalizedScopeName.empty() || NormalizedScopeName == "gnu" || NormalizedScopeName == "clang")); StringRef AttrName = Name->getName(); - if (ShouldNormalize && AttrName.size() >= 4 && AttrName.startswith("__") && - AttrName.endswith("__")) + if (ShouldNormalize && AttrName.size() >= 4 && AttrName.starts_with("__") && + AttrName.ends_with("__")) AttrName = AttrName.slice(2, AttrName.size() - 2); return AttrName; @@ -85,6 +114,10 @@ bool AttributeCommonInfo::isGNUScope() const { return ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__")); } +bool AttributeCommonInfo::isClangScope() const { + return ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang")); +} + #include "clang/Sema/AttrParsedAttrKinds.inc" static SmallString<64> normalizeName(const IdentifierInfo *Name, @@ -96,7 +129,7 @@ static SmallString<64> normalizeName(const IdentifierInfo *Name, SmallString<64> FullName = ScopeName; if (!ScopeName.empty()) { assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 || - SyntaxUsed == AttributeCommonInfo::AS_C2x); + SyntaxUsed == AttributeCommonInfo::AS_C23); FullName += "::"; } FullName += AttrName; diff --git a/contrib/llvm-project/clang/lib/Basic/BuiltinTargetFeatures.h b/contrib/llvm-project/clang/lib/Basic/BuiltinTargetFeatures.h new file mode 100644 index 000000000000..9754acda2a68 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Basic/BuiltinTargetFeatures.h @@ -0,0 +1,95 @@ +//===-- CodeGenFunction.h - Target features for builtin ---------*- 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 is the internal required target features for builtin. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H +#define LLVM_CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" + +using llvm::StringRef; + +namespace clang { +namespace Builtin { +/// TargetFeatures - This class is used to check whether the builtin function +/// has the required tagert specific features. It is able to support the +/// combination of ','(and), '|'(or), and '()'. By default, the priority of +/// ',' is higher than that of '|' . +/// E.g: +/// A,B|C means the builtin function requires both A and B, or C. +/// If we want the builtin function requires both A and B, or both A and C, +/// there are two ways: A,B|A,C or A,(B|C). +/// The FeaturesList should not contain spaces, and brackets must appear in +/// pairs. +class TargetFeatures { + struct FeatureListStatus { + bool HasFeatures; + StringRef CurFeaturesList; + }; + + const llvm::StringMap<bool> &CallerFeatureMap; + + FeatureListStatus getAndFeatures(StringRef FeatureList) { + int InParentheses = 0; + bool HasFeatures = true; + size_t SubexpressionStart = 0; + for (size_t i = 0, e = FeatureList.size(); i < e; ++i) { + char CurrentToken = FeatureList[i]; + switch (CurrentToken) { + default: + break; + case '(': + if (InParentheses == 0) + SubexpressionStart = i + 1; + ++InParentheses; + break; + case ')': + --InParentheses; + assert(InParentheses >= 0 && "Parentheses are not in pair"); + [[fallthrough]]; + case '|': + case ',': + if (InParentheses == 0) { + if (HasFeatures && i != SubexpressionStart) { + StringRef F = FeatureList.slice(SubexpressionStart, i); + HasFeatures = CurrentToken == ')' ? hasRequiredFeatures(F) + : CallerFeatureMap.lookup(F); + } + SubexpressionStart = i + 1; + if (CurrentToken == '|') { + return {HasFeatures, FeatureList.substr(SubexpressionStart)}; + } + } + break; + } + } + assert(InParentheses == 0 && "Parentheses are not in pair"); + if (HasFeatures && SubexpressionStart != FeatureList.size()) + HasFeatures = + CallerFeatureMap.lookup(FeatureList.substr(SubexpressionStart)); + return {HasFeatures, StringRef()}; + } + +public: + bool hasRequiredFeatures(StringRef FeatureList) { + FeatureListStatus FS = {false, FeatureList}; + while (!FS.HasFeatures && !FS.CurFeaturesList.empty()) + FS = getAndFeatures(FS.CurFeaturesList); + return FS.HasFeatures; + } + + TargetFeatures(const llvm::StringMap<bool> &CallerFeatureMap) + : CallerFeatureMap(CallerFeatureMap) {} +}; + +} // namespace Builtin +} // namespace clang +#endif /* CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H */ diff --git a/contrib/llvm-project/clang/lib/Basic/Builtins.cpp b/contrib/llvm-project/clang/lib/Basic/Builtins.cpp index 7118aa9dc210..d366989bafc5 100644 --- a/contrib/llvm-project/clang/lib/Basic/Builtins.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Builtins.cpp @@ -11,20 +11,33 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/Builtins.h" +#include "BuiltinTargetFeatures.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/StringRef.h" using namespace clang; -static const Builtin::Info BuiltinInfo[] = { - { "not a builtin function", nullptr, nullptr, nullptr, ALL_LANGUAGES,nullptr}, +const char *HeaderDesc::getName() const { + switch (ID) { +#define HEADER(ID, NAME) \ + case ID: \ + return NAME; +#include "clang/Basic/BuiltinHeaders.def" +#undef HEADER + }; + llvm_unreachable("Unknown HeaderDesc::HeaderID enum"); +} + +static constexpr Builtin::Info BuiltinInfo[] = { + {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER, + ALL_LANGUAGES}, #define BUILTIN(ID, TYPE, ATTRS) \ - { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define LANGBUILTIN(ID, TYPE, ATTRS, LANGS) \ - { #ID, TYPE, ATTRS, nullptr, LANGS, nullptr }, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS}, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS) \ - { #ID, TYPE, ATTRS, HEADER, LANGS, nullptr }, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS}, #include "clang/Basic/Builtins.def" }; @@ -48,43 +61,65 @@ void Builtin::Context::InitializeTarget(const TargetInfo &Target, } bool Builtin::Context::isBuiltinFunc(llvm::StringRef FuncName) { - for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin; ++i) - if (FuncName.equals(BuiltinInfo[i].Name)) + bool InStdNamespace = FuncName.consume_front("std-"); + for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin; + ++i) { + if (FuncName.equals(BuiltinInfo[i].Name) && + (bool)strchr(BuiltinInfo[i].Attributes, 'z') == InStdNamespace) return strchr(BuiltinInfo[i].Attributes, 'f') != nullptr; + } return false; } -bool Builtin::Context::builtinIsSupported(const Builtin::Info &BuiltinInfo, - const LangOptions &LangOpts) { - bool BuiltinsUnsupported = - (LangOpts.NoBuiltin || LangOpts.isNoBuiltinFunc(BuiltinInfo.Name)) && - strchr(BuiltinInfo.Attributes, 'f'); - bool CorBuiltinsUnsupported = - !LangOpts.Coroutines && (BuiltinInfo.Langs & COR_LANG); - bool MathBuiltinsUnsupported = - LangOpts.NoMathBuiltin && BuiltinInfo.HeaderName && - llvm::StringRef(BuiltinInfo.HeaderName).equals("math.h"); - bool GnuModeUnsupported = !LangOpts.GNUMode && (BuiltinInfo.Langs & GNU_LANG); - bool MSModeUnsupported = - !LangOpts.MicrosoftExt && (BuiltinInfo.Langs & MS_LANG); - bool ObjCUnsupported = !LangOpts.ObjC && BuiltinInfo.Langs == OBJC_LANG; - bool OclC1Unsupported = (LangOpts.OpenCLVersion / 100) != 1 && - (BuiltinInfo.Langs & ALL_OCLC_LANGUAGES ) == OCLC1X_LANG; - bool OclC2Unsupported = - (LangOpts.OpenCLVersion != 200 && !LangOpts.OpenCLCPlusPlus) && - (BuiltinInfo.Langs & ALL_OCLC_LANGUAGES) == OCLC20_LANG; - bool OclCUnsupported = !LangOpts.OpenCL && - (BuiltinInfo.Langs & ALL_OCLC_LANGUAGES); - bool OpenMPUnsupported = !LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG; - bool CUDAUnsupported = !LangOpts.CUDA && BuiltinInfo.Langs == CUDA_LANG; - bool CPlusPlusUnsupported = - !LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG; - return !BuiltinsUnsupported && !CorBuiltinsUnsupported && - !MathBuiltinsUnsupported && !OclCUnsupported && !OclC1Unsupported && - !OclC2Unsupported && !OpenMPUnsupported && !GnuModeUnsupported && - !MSModeUnsupported && !ObjCUnsupported && !CPlusPlusUnsupported && - !CUDAUnsupported; +/// Is this builtin supported according to the given language options? +static bool builtinIsSupported(const Builtin::Info &BuiltinInfo, + const LangOptions &LangOpts) { + /* Builtins Unsupported */ + if (LangOpts.NoBuiltin && strchr(BuiltinInfo.Attributes, 'f') != nullptr) + return false; + /* CorBuiltins Unsupported */ + if (!LangOpts.Coroutines && (BuiltinInfo.Langs & COR_LANG)) + return false; + /* MathBuiltins Unsupported */ + if (LangOpts.NoMathBuiltin && BuiltinInfo.Header.ID == HeaderDesc::MATH_H) + return false; + /* GnuMode Unsupported */ + if (!LangOpts.GNUMode && (BuiltinInfo.Langs & GNU_LANG)) + return false; + /* MSMode Unsupported */ + if (!LangOpts.MicrosoftExt && (BuiltinInfo.Langs & MS_LANG)) + return false; + /* ObjC Unsupported */ + if (!LangOpts.ObjC && BuiltinInfo.Langs == OBJC_LANG) + return false; + /* OpenCLC Unsupported */ + if (!LangOpts.OpenCL && (BuiltinInfo.Langs & ALL_OCL_LANGUAGES)) + return false; + /* OopenCL GAS Unsupported */ + if (!LangOpts.OpenCLGenericAddressSpace && (BuiltinInfo.Langs & OCL_GAS)) + return false; + /* OpenCL Pipe Unsupported */ + if (!LangOpts.OpenCLPipes && (BuiltinInfo.Langs & OCL_PIPE)) + return false; + + // Device side enqueue is not supported until OpenCL 2.0. In 2.0 and higher + // support is indicated with language option for blocks. + + /* OpenCL DSE Unsupported */ + if ((LangOpts.getOpenCLCompatibleVersion() < 200 || !LangOpts.Blocks) && + (BuiltinInfo.Langs & OCL_DSE)) + return false; + /* OpenMP Unsupported */ + if (!LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG) + return false; + /* CUDA Unsupported */ + if (!LangOpts.CUDA && BuiltinInfo.Langs == CUDA_LANG) + return false; + /* CPlusPlus Unsupported */ + if (!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG) + return false; + return true; } /// initializeBuiltins - Mark the identifiers for all the builtins with their @@ -107,6 +142,19 @@ void Builtin::Context::initializeBuiltins(IdentifierTable &Table, for (unsigned i = 0, e = AuxTSRecords.size(); i != e; ++i) Table.get(AuxTSRecords[i].Name) .setBuiltinID(i + Builtin::FirstTSBuiltin + TSRecords.size()); + + // Step #4: Unregister any builtins specified by -fno-builtin-foo. + for (llvm::StringRef Name : LangOpts.NoBuiltinFuncs) { + bool InStdNamespace = Name.consume_front("std-"); + auto NameIt = Table.find(Name); + if (NameIt != Table.end()) { + unsigned ID = NameIt->second->getBuiltinID(); + if (ID != Builtin::NotBuiltin && isPredefinedLibFunction(ID) && + isInStdNamespace(ID) == InStdNamespace) { + NameIt->second->clearBuiltinID(); + } + } + } } unsigned Builtin::Context::getRequiredVectorWidth(unsigned ID) const { @@ -186,8 +234,19 @@ bool Builtin::Context::performsCallback(unsigned ID, } bool Builtin::Context::canBeRedeclared(unsigned ID) const { - return ID == Builtin::NotBuiltin || - ID == Builtin::BI__va_start || - (!hasReferenceArgsOrResult(ID) && - !hasCustomTypechecking(ID)); + return ID == Builtin::NotBuiltin || ID == Builtin::BI__va_start || + ID == Builtin::BI__builtin_assume_aligned || + (!hasReferenceArgsOrResult(ID) && !hasCustomTypechecking(ID)) || + isInStdNamespace(ID); +} + +bool Builtin::evaluateRequiredTargetFeatures( + StringRef RequiredFeatures, const llvm::StringMap<bool> &TargetFetureMap) { + // Return true if the builtin doesn't have any required features. + if (RequiredFeatures.empty()) + return true; + assert(!RequiredFeatures.contains(' ') && "Space in feature list"); + + TargetFeatures TF(TargetFetureMap); + return TF.hasRequiredFeatures(RequiredFeatures); } diff --git a/contrib/llvm-project/clang/lib/Basic/CLWarnings.cpp b/contrib/llvm-project/clang/lib/Basic/CLWarnings.cpp new file mode 100644 index 000000000000..5449d8f59fcf --- /dev/null +++ b/contrib/llvm-project/clang/lib/Basic/CLWarnings.cpp @@ -0,0 +1,29 @@ +//===--- CLWarnings.h - Maps some cl.exe warning ids -----------*- 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 implements the Diagnostic-related interfaces. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/CLWarnings.h" +#include "clang/Basic/DiagnosticCategories.h" +#include <optional> + +using namespace clang; + +std::optional<diag::Group> +clang::diagGroupFromCLWarningID(unsigned CLWarningID) { + switch (CLWarningID) { + case 4005: return diag::Group::MacroRedefined; + case 4018: return diag::Group::SignCompare; + case 4100: return diag::Group::UnusedParameter; + case 4910: return diag::Group::DllexportExplicitInstantiationDecl; + case 4996: return diag::Group::DeprecatedDeclarations; + } + return {}; +} diff --git a/contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp b/contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp index 0c609cfa61de..79d715305ef2 100644 --- a/contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp +++ b/contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp @@ -20,4 +20,41 @@ CodeGenOptions::CodeGenOptions() { memcpy(CoverageVersion, "408*", 4); } +void CodeGenOptions::resetNonModularOptions(StringRef ModuleFormat) { + // First reset all CodeGen options only. The Debug options are handled later. +#define DEBUGOPT(Name, Bits, Default) +#define VALUE_DEBUGOPT(Name, Bits, Default) +#define ENUM_DEBUGOPT(Name, Type, Bits, Default) +#define CODEGENOPT(Name, Bits, Default) Name = Default; +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) set##Name(Default); +// Do not reset AST affecting code generation options. +#define AFFECTING_VALUE_CODEGENOPT(Name, Bits, Default) +#include "clang/Basic/CodeGenOptions.def" + + // Next reset all debug options that can always be reset, because they never + // affect the PCM. +#define DEBUGOPT(Name, Bits, Default) +#define VALUE_DEBUGOPT(Name, Bits, Default) +#define ENUM_DEBUGOPT(Name, Type, Bits, Default) +#define BENIGN_DEBUGOPT(Name, Bits, Default) Name = Default; +#define BENIGN_VALUE_DEBUGOPT(Name, Bits, Default) Name = Default; +#define BENIGN_ENUM_DEBUGOPT(Name, Type, Bits, Default) set##Name(Default); +#include "clang/Basic/DebugOptions.def" + + // Conditionally reset debug options that only matter when the debug info is + // emitted into the PCM (-gmodules). + if (ModuleFormat == "raw" && !DebugTypeExtRefs) { +#define DEBUGOPT(Name, Bits, Default) Name = Default; +#define VALUE_DEBUGOPT(Name, Bits, Default) Name = Default; +#define ENUM_DEBUGOPT(Name, Type, Bits, Default) set##Name(Default); +#define BENIGN_DEBUGOPT(Name, Bits, Default) +#define BENIGN_VALUE_DEBUGOPT(Name, Bits, Default) +#define BENIGN_ENUM_DEBUGOPT(Name, Type, Bits, Default) +#include "clang/Basic/DebugOptions.def" + } + + RelocationModel = llvm::Reloc::PIC_; + memcpy(CoverageVersion, "408*", 4); +} + } // end namespace clang diff --git a/contrib/llvm-project/clang/lib/Basic/Cuda.cpp b/contrib/llvm-project/clang/lib/Basic/Cuda.cpp index 766135bcb376..1b1da6a1356f 100644 --- a/contrib/llvm-project/clang/lib/Basic/Cuda.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Cuda.cpp @@ -1,60 +1,72 @@ #include "clang/Basic/Cuda.h" #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" namespace clang { -const char *CudaVersionToString(CudaVersion V) { - switch (V) { - case CudaVersion::UNKNOWN: - return "unknown"; - case CudaVersion::CUDA_70: - return "7.0"; - case CudaVersion::CUDA_75: - return "7.5"; - case CudaVersion::CUDA_80: - return "8.0"; - case CudaVersion::CUDA_90: - return "9.0"; - case CudaVersion::CUDA_91: - return "9.1"; - case CudaVersion::CUDA_92: - return "9.2"; - case CudaVersion::CUDA_100: - return "10.0"; - case CudaVersion::CUDA_101: - return "10.1"; - case CudaVersion::CUDA_102: - return "10.2"; - case CudaVersion::CUDA_110: - return "11.0"; - case CudaVersion::CUDA_111: - return "11.1"; - case CudaVersion::CUDA_112: - return "11.2"; +struct CudaVersionMapEntry { + const char *Name; + CudaVersion Version; + llvm::VersionTuple TVersion; +}; +#define CUDA_ENTRY(major, minor) \ + { \ +#major "." #minor, CudaVersion::CUDA_##major##minor, \ + llvm::VersionTuple(major, minor) \ } - llvm_unreachable("invalid enum"); + +static const CudaVersionMapEntry CudaNameVersionMap[] = { + CUDA_ENTRY(7, 0), + CUDA_ENTRY(7, 5), + CUDA_ENTRY(8, 0), + CUDA_ENTRY(9, 0), + CUDA_ENTRY(9, 1), + CUDA_ENTRY(9, 2), + CUDA_ENTRY(10, 0), + CUDA_ENTRY(10, 1), + CUDA_ENTRY(10, 2), + CUDA_ENTRY(11, 0), + CUDA_ENTRY(11, 1), + CUDA_ENTRY(11, 2), + CUDA_ENTRY(11, 3), + CUDA_ENTRY(11, 4), + CUDA_ENTRY(11, 5), + CUDA_ENTRY(11, 6), + CUDA_ENTRY(11, 7), + CUDA_ENTRY(11, 8), + CUDA_ENTRY(12, 0), + CUDA_ENTRY(12, 1), + CUDA_ENTRY(12, 2), + CUDA_ENTRY(12, 3), + {"", CudaVersion::NEW, llvm::VersionTuple(std::numeric_limits<int>::max())}, + {"unknown", CudaVersion::UNKNOWN, {}} // End of list tombstone. +}; +#undef CUDA_ENTRY + +const char *CudaVersionToString(CudaVersion V) { + for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I) + if (I->Version == V) + return I->Name; + + return CudaVersionToString(CudaVersion::UNKNOWN); } 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) - .Case("9.0", CudaVersion::CUDA_90) - .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.2", CudaVersion::CUDA_102) - .Case("11.0", CudaVersion::CUDA_110) - .Case("11.1", CudaVersion::CUDA_111) - .Case("11.2", CudaVersion::CUDA_112) - .Default(CudaVersion::UNKNOWN); + std::string VS = S.str(); + for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I) + if (I->Name == VS) + return I->Version; + return CudaVersion::UNKNOWN; +} + +CudaVersion ToCudaVersion(llvm::VersionTuple Version) { + for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I) + if (I->TVersion == Version) + return I->Version; + return CudaVersion::UNKNOWN; } namespace { @@ -80,6 +92,10 @@ static const CudaArchToStringMap arch_names[] = { SM(70), SM(72), // Volta SM(75), // Turing SM(80), SM(86), // Ampere + SM(87), // Jetson/Drive AGX Orin + SM(89), // Ada Lovelace + SM(90), // Hopper + SM(90a), // Hopper GFX(600), // gfx600 GFX(601), // gfx601 GFX(602), // gfx602 @@ -102,6 +118,9 @@ static const CudaArchToStringMap arch_names[] = { GFX(909), // gfx909 GFX(90a), // gfx90a GFX(90c), // gfx90c + GFX(940), // gfx940 + GFX(941), // gfx941 + GFX(942), // gfx942 GFX(1010), // gfx1010 GFX(1011), // gfx1011 GFX(1012), // gfx1012 @@ -112,6 +131,16 @@ static const CudaArchToStringMap arch_names[] = { GFX(1033), // gfx1033 GFX(1034), // gfx1034 GFX(1035), // gfx1035 + GFX(1036), // gfx1036 + GFX(1100), // gfx1100 + GFX(1101), // gfx1101 + GFX(1102), // gfx1102 + GFX(1103), // gfx1103 + GFX(1150), // gfx1150 + GFX(1151), // gfx1151 + GFX(1200), // gfx1200 + GFX(1201), // gfx1201 + {CudaArch::Generic, "generic", ""}, // clang-format on }; #undef SM @@ -178,6 +207,13 @@ CudaVersion MinVersionForCudaArch(CudaArch A) { return CudaVersion::CUDA_110; case CudaArch::SM_86: return CudaVersion::CUDA_111; + case CudaArch::SM_87: + return CudaVersion::CUDA_114; + case CudaArch::SM_89: + case CudaArch::SM_90: + return CudaVersion::CUDA_118; + case CudaArch::SM_90a: + return CudaVersion::CUDA_120; default: llvm_unreachable("invalid enum"); } @@ -186,7 +222,7 @@ CudaVersion MinVersionForCudaArch(CudaArch A) { CudaVersion MaxVersionForCudaArch(CudaArch A) { // AMD GPUs do not depend on CUDA versions. if (IsAMDGpuArch(A)) - return CudaVersion::LATEST; + return CudaVersion::NEW; switch (A) { case CudaArch::UNKNOWN: @@ -194,41 +230,14 @@ CudaVersion MaxVersionForCudaArch(CudaArch A) { case CudaArch::SM_20: case CudaArch::SM_21: return CudaVersion::CUDA_80; - default: - return CudaVersion::LATEST; - } -} - -CudaVersion ToCudaVersion(llvm::VersionTuple Version) { - int IVer = - Version.getMajor() * 10 + Version.getMinor().getValueOr(0); - switch(IVer) { - case 70: - return CudaVersion::CUDA_70; - case 75: - return CudaVersion::CUDA_75; - case 80: - return CudaVersion::CUDA_80; - case 90: - return CudaVersion::CUDA_90; - case 91: - return CudaVersion::CUDA_91; - case 92: - return CudaVersion::CUDA_92; - case 100: - return CudaVersion::CUDA_100; - case 101: - return CudaVersion::CUDA_101; - case 102: + case CudaArch::SM_30: + case CudaArch::SM_32: return CudaVersion::CUDA_102; - case 110: - return CudaVersion::CUDA_110; - case 111: - return CudaVersion::CUDA_111; - case 112: - return CudaVersion::CUDA_112; + case CudaArch::SM_35: + case CudaArch::SM_37: + return CudaVersion::CUDA_118; default: - return CudaVersion::UNKNOWN; + return CudaVersion::NEW; } } diff --git a/contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp b/contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp index fe35f77782c9..00aa5f9e63cd 100644 --- a/contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp +++ b/contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp @@ -11,12 +11,13 @@ #include "llvm/Support/JSON.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" +#include <optional> using namespace clang; -Optional<VersionTuple> DarwinSDKInfo::RelatedTargetVersionMapping::map( +std::optional<VersionTuple> DarwinSDKInfo::RelatedTargetVersionMapping::map( const VersionTuple &Key, const VersionTuple &MinimumValue, - Optional<VersionTuple> MaximumValue) const { + std::optional<VersionTuple> MaximumValue) const { if (Key < MinimumKeyVersion) return MinimumValue; if (Key > MaximumKeyVersion) @@ -29,11 +30,11 @@ Optional<VersionTuple> DarwinSDKInfo::RelatedTargetVersionMapping::map( // the major-only check. if (Key.getMinor()) return map(VersionTuple(Key.getMajor()), MinimumValue, MaximumValue); - // If this a major only key, return None for a missing entry. - return None; + // If this a major only key, return std::nullopt for a missing entry. + return std::nullopt; } -Optional<DarwinSDKInfo::RelatedTargetVersionMapping> +std::optional<DarwinSDKInfo::RelatedTargetVersionMapping> DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON( const llvm::json::Object &Obj, VersionTuple MaximumDeploymentTarget) { VersionTuple Min = VersionTuple(std::numeric_limits<unsigned>::max()); @@ -45,7 +46,7 @@ DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON( llvm::VersionTuple KeyVersion; llvm::VersionTuple ValueVersion; if (KeyVersion.tryParse(KV.getFirst()) || ValueVersion.tryParse(*Val)) - return None; + return std::nullopt; Mapping[KeyVersion.normalize()] = ValueVersion; if (KeyVersion < Min) Min = KeyVersion; @@ -56,39 +57,59 @@ DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON( } } if (Mapping.empty()) - return None; + return std::nullopt; return RelatedTargetVersionMapping( Min, Max, MinValue, MaximumDeploymentTarget, std::move(Mapping)); } -static Optional<VersionTuple> getVersionKey(const llvm::json::Object &Obj, - StringRef Key) { +static std::optional<VersionTuple> getVersionKey(const llvm::json::Object &Obj, + StringRef Key) { auto Value = Obj.getString(Key); if (!Value) - return None; + return std::nullopt; VersionTuple Version; if (Version.tryParse(*Value)) - return None; + return std::nullopt; return Version; } -Optional<DarwinSDKInfo> +std::optional<DarwinSDKInfo> DarwinSDKInfo::parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj) { auto Version = getVersionKey(*Obj, "Version"); if (!Version) - return None; + return std::nullopt; auto MaximumDeploymentVersion = getVersionKey(*Obj, "MaximumDeploymentTarget"); if (!MaximumDeploymentVersion) - return None; - llvm::DenseMap<OSEnvPair::StorageType, Optional<RelatedTargetVersionMapping>> + return std::nullopt; + llvm::DenseMap<OSEnvPair::StorageType, + std::optional<RelatedTargetVersionMapping>> VersionMappings; if (const auto *VM = Obj->getObject("VersionMap")) { + // FIXME: Generalize this out beyond iOS-deriving targets. + // Look for ios_<targetos> version mapping for targets that derive from ios. + for (const auto &KV : *VM) { + auto Pair = StringRef(KV.getFirst()).split("_"); + if (Pair.first.compare_insensitive("ios") == 0) { + llvm::Triple TT(llvm::Twine("--") + Pair.second.lower()); + if (TT.getOS() != llvm::Triple::UnknownOS) { + auto Mapping = RelatedTargetVersionMapping::parseJSON( + *KV.getSecond().getAsObject(), *MaximumDeploymentVersion); + if (Mapping) + VersionMappings[OSEnvPair(llvm::Triple::IOS, + llvm::Triple::UnknownEnvironment, + TT.getOS(), + llvm::Triple::UnknownEnvironment) + .Value] = std::move(Mapping); + } + } + } + if (const auto *Mapping = VM->getObject("macOS_iOSMac")) { auto VersionMap = RelatedTargetVersionMapping::parseJSON( *Mapping, *MaximumDeploymentVersion); if (!VersionMap) - return None; + return std::nullopt; VersionMappings[OSEnvPair::macOStoMacCatalystPair().Value] = std::move(VersionMap); } @@ -96,7 +117,7 @@ DarwinSDKInfo::parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj) { auto VersionMap = RelatedTargetVersionMapping::parseJSON( *Mapping, *MaximumDeploymentVersion); if (!VersionMap) - return None; + return std::nullopt; VersionMappings[OSEnvPair::macCatalystToMacOSPair().Value] = std::move(VersionMap); } @@ -107,7 +128,7 @@ DarwinSDKInfo::parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj) { std::move(VersionMappings)); } -Expected<Optional<DarwinSDKInfo>> +Expected<std::optional<DarwinSDKInfo>> clang::parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath) { llvm::SmallString<256> Filepath = SDKRootPath; llvm::sys::path::append(Filepath, "SDKSettings.json"); @@ -115,7 +136,7 @@ clang::parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath) { VFS.getBufferForFile(Filepath); if (!File) { // If the file couldn't be read, assume it just doesn't exist. - return None; + return std::nullopt; } Expected<llvm::json::Value> Result = llvm::json::parse(File.get()->getBuffer()); diff --git a/contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp b/contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp index d3b2122e9c59..0208ccc31bd7 100644 --- a/contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp @@ -25,8 +25,9 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/ConvertUTF.h" #include "llvm/Support/CrashRecoveryContext.h" -#include "llvm/Support/Locale.h" +#include "llvm/Support/Unicode.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> @@ -42,28 +43,12 @@ using namespace clang; const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB, DiagNullabilityKind nullability) { - StringRef string; - switch (nullability.first) { - case NullabilityKind::NonNull: - string = nullability.second ? "'nonnull'" : "'_Nonnull'"; - break; - - case NullabilityKind::Nullable: - string = nullability.second ? "'nullable'" : "'_Nullable'"; - break; - - case NullabilityKind::Unspecified: - string = nullability.second ? "'null_unspecified'" : "'_Null_unspecified'"; - break; - - case NullabilityKind::NullableResult: - assert(!nullability.second && - "_Nullable_result isn't supported as context-sensitive keyword"); - string = "_Nullable_result"; - break; - } - - DB.AddString(string); + DB.AddString( + ("'" + + getNullabilitySpelling(nullability.first, + /*isContextSensitive=*/nullability.second) + + "'") + .str()); return DB; } @@ -130,7 +115,7 @@ bool DiagnosticsEngine::popMappings(SourceLocation Loc) { return true; } -void DiagnosticsEngine::Reset() { +void DiagnosticsEngine::Reset(bool soft /*=false*/) { ErrorOccurred = false; UncompilableErrorOccurred = false; FatalErrorOccurred = false; @@ -145,15 +130,17 @@ void DiagnosticsEngine::Reset() { LastDiagLevel = DiagnosticIDs::Ignored; DelayedDiagID = 0; - // Clear state related to #pragma diagnostic. - DiagStates.clear(); - DiagStatesByLoc.clear(); - DiagStateOnPushStack.clear(); + if (!soft) { + // Clear state related to #pragma diagnostic. + DiagStates.clear(); + DiagStatesByLoc.clear(); + DiagStateOnPushStack.clear(); - // Create a DiagState and DiagStatePoint representing diagnostic changes - // through command-line. - DiagStates.emplace_back(); - DiagStatesByLoc.appendFirst(&DiagStates.back()); + // Create a DiagState and DiagStatePoint representing diagnostic changes + // through command-line. + DiagStates.emplace_back(); + DiagStatesByLoc.appendFirst(&DiagStates.back()); + } } void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1, @@ -173,6 +160,18 @@ void DiagnosticsEngine::ReportDelayed() { Report(ID) << DelayedDiagArg1 << DelayedDiagArg2 << DelayedDiagArg3; } +DiagnosticMapping & +DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) { + std::pair<iterator, bool> Result = + DiagMap.insert(std::make_pair(Diag, DiagnosticMapping())); + + // Initialize the entry if we added it. + if (Result.second) + Result.first->second = DiagnosticIDs::getDefaultMapping(Diag); + + return Result.first->second; +} + void DiagnosticsEngine::DiagStateMap::appendFirst(DiagState *State) { assert(Files.empty() && "not first"); FirstDiagState = CurDiagState = State; @@ -374,6 +373,12 @@ void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map, DiagnosticMapping Mapping = makeUserMapping(Map, L); Mapping.setUpgradedFromWarning(WasUpgradedFromWarning); + // Make sure we propagate the NoWarningAsError flag from an existing + // mapping (which may be the default mapping). + DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag); + Mapping.setNoWarningAsError(Info.hasNoWarningAsError() || + Mapping.hasNoWarningAsError()); + // Common case; setting all the diagnostics of a group in one place. if ((L.isInvalid() || L == DiagStatesByLoc.getCurDiagStateLoc()) && DiagStatesByLoc.getCurDiagState()) { @@ -408,6 +413,14 @@ bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor, return false; } +bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor, + diag::Group Group, + diag::Severity Map, + SourceLocation Loc) { + return setSeverityForGroup(Flavor, Diags->getWarningOptionForGroup(Group), + Map, Loc); +} + bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled) { // If we are enabling this feature, just set the diagnostic mappings to map to @@ -776,8 +789,8 @@ static const char *getTokenDescForDiagnostic(tok::TokenKind Kind) { /// array. void Diagnostic:: FormatDiagnostic(SmallVectorImpl<char> &OutStr) const { - if (!StoredDiagMessage.empty()) { - OutStr.append(StoredDiagMessage.begin(), StoredDiagMessage.end()); + if (StoredDiagMessage.has_value()) { + OutStr.append(StoredDiagMessage->begin(), StoredDiagMessage->end()); return; } @@ -787,6 +800,51 @@ FormatDiagnostic(SmallVectorImpl<char> &OutStr) const { FormatDiagnostic(Diag.begin(), Diag.end(), OutStr); } +/// EscapeStringForDiagnostic - Append Str to the diagnostic buffer, +/// escaping non-printable characters and ill-formed code unit sequences. +void clang::EscapeStringForDiagnostic(StringRef Str, + SmallVectorImpl<char> &OutStr) { + OutStr.reserve(OutStr.size() + Str.size()); + auto *Begin = reinterpret_cast<const unsigned char *>(Str.data()); + llvm::raw_svector_ostream OutStream(OutStr); + const unsigned char *End = Begin + Str.size(); + while (Begin != End) { + // ASCII case + if (isPrintable(*Begin) || isWhitespace(*Begin)) { + OutStream << *Begin; + ++Begin; + continue; + } + if (llvm::isLegalUTF8Sequence(Begin, End)) { + llvm::UTF32 CodepointValue; + llvm::UTF32 *CpPtr = &CodepointValue; + const unsigned char *CodepointBegin = Begin; + const unsigned char *CodepointEnd = + Begin + llvm::getNumBytesForUTF8(*Begin); + llvm::ConversionResult Res = llvm::ConvertUTF8toUTF32( + &Begin, CodepointEnd, &CpPtr, CpPtr + 1, llvm::strictConversion); + (void)Res; + assert( + llvm::conversionOK == Res && + "the sequence is legal UTF-8 but we couldn't convert it to UTF-32"); + assert(Begin == CodepointEnd && + "we must be further along in the string now"); + if (llvm::sys::unicode::isPrintable(CodepointValue) || + llvm::sys::unicode::isFormatting(CodepointValue)) { + OutStr.append(CodepointBegin, CodepointEnd); + continue; + } + // Unprintable code point. + OutStream << "<U+" << llvm::format_hex_no_prefix(CodepointValue, 4, true) + << ">"; + continue; + } + // Invalid code unit. + OutStream << "<" << llvm::format_hex_no_prefix(*Begin, 2, true) << ">"; + ++Begin; + } +} + void Diagnostic:: FormatDiagnostic(const char *DiagStr, const char *DiagEnd, SmallVectorImpl<char> &OutStr) const { @@ -797,11 +855,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, StringRef(DiagStr, DiagEnd - DiagStr).equals("%0") && getArgKind(0) == DiagnosticsEngine::ak_std_string) { const std::string &S = getArgStdStr(0); - for (char c : S) { - if (llvm::sys::locale::isPrint(c) || c == '\t') { - OutStr.push_back(c); - } - } + EscapeStringForDiagnostic(S, OutStr); return; } @@ -908,7 +962,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, case DiagnosticsEngine::ak_std_string: { const std::string &S = getArgStdStr(ArgNo); assert(ModifierLen == 0 && "No modifiers for strings yet"); - OutStr.append(S.begin(), S.end()); + EscapeStringForDiagnostic(S, OutStr); break; } case DiagnosticsEngine::ak_c_string: { @@ -918,13 +972,12 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, // Don't crash if get passed a null pointer by accident. if (!S) S = "(null)"; - - OutStr.append(S, S + strlen(S)); + EscapeStringForDiagnostic(S, OutStr); break; } // ---- INTEGERS ---- case DiagnosticsEngine::ak_sint: { - int Val = getArgSInt(ArgNo); + int64_t Val = getArgSInt(ArgNo); if (ModifierIs(Modifier, ModifierLen, "select")) { HandleSelectModifier(*this, (unsigned)Val, Argument, ArgumentLen, @@ -943,7 +996,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, break; } case DiagnosticsEngine::ak_uint: { - unsigned Val = getArgUInt(ArgNo); + uint64_t Val = getArgUInt(ArgNo); if (ModifierIs(Modifier, ModifierLen, "select")) { HandleSelectModifier(*this, Val, Argument, ArgumentLen, OutStr); @@ -969,13 +1022,13 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, if (const char *S = tok::getPunctuatorSpelling(Kind)) // Quoted token spelling for punctuators. Out << '\'' << S << '\''; - else if (const char *S = tok::getKeywordSpelling(Kind)) + else if ((S = tok::getKeywordSpelling(Kind))) // Unquoted token spelling for keywords. Out << S; - else if (const char *S = getTokenDescForDiagnostic(Kind)) + else if ((S = getTokenDescForDiagnostic(Kind))) // Unquoted translatable token name. Out << S; - else if (const char *S = tok::getTokenName(Kind)) + else if ((S = tok::getTokenName(Kind))) // Debug name, shouldn't appear in user-facing diagnostics. Out << '<' << S << '>'; else @@ -1124,6 +1177,14 @@ StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, { } +llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS, + const StoredDiagnostic &SD) { + if (SD.getLocation().hasManager()) + OS << SD.getLocation().printToString(SD.getLocation().getManager()) << ": "; + OS << SD.getMessage(); + return OS; +} + /// IncludeInDiagnosticCounts - This method (whose default implementation /// returns true) indicates whether the diagnostics handled by this /// DiagnosticConsumer should be included in the number of diagnostics diff --git a/contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp b/contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp index c333076d2efc..6c7bd50eefb7 100644 --- a/contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp +++ b/contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ErrorHandling.h" #include <map> +#include <optional> using namespace clang; //===----------------------------------------------------------------------===// @@ -33,7 +34,7 @@ struct StaticDiagInfoRec; // platforms. See "How To Write Shared Libraries" by Ulrich Drepper. struct StaticDiagInfoDescriptionStringTable { #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ char ENUM##_desc[sizeof(DESC)]; // clang-format off #include "clang/Basic/DiagnosticCommonKinds.inc" @@ -54,7 +55,7 @@ struct StaticDiagInfoDescriptionStringTable { const StaticDiagInfoDescriptionStringTable StaticDiagInfoDescriptions = { #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ DESC, // clang-format off #include "clang/Basic/DiagnosticCommonKinds.inc" @@ -79,7 +80,7 @@ extern const StaticDiagInfoRec StaticDiagInfo[]; // StaticDiagInfoRec would have extra padding on 64-bit platforms. const uint32_t StaticDiagInfoDescriptionOffsets[] = { #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ offsetof(StaticDiagInfoDescriptionStringTable, ENUM##_desc), // clang-format off #include "clang/Basic/DiagnosticCommonKinds.inc" @@ -115,6 +116,7 @@ struct StaticDiagInfoRec { uint8_t Category : 6; uint8_t WarnNoWerror : 1; uint8_t WarnShowInSystemHeader : 1; + uint8_t WarnShowInSystemMacro : 1; uint16_t OptionGroupIndex : 15; uint16_t Deferrable : 1; @@ -170,7 +172,7 @@ VALIDATE_DIAG_SIZE(REFACTORING) const StaticDiagInfoRec StaticDiagInfo[] = { // clang-format off #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ { \ diag::ENUM, \ DEFAULT_SEVERITY, \ @@ -179,6 +181,7 @@ const StaticDiagInfoRec StaticDiagInfo[] = { CATEGORY, \ NOWERROR, \ SHOWINSYSHEADER, \ + SHOWINSYSMACRO, \ GROUP, \ DEFERRABLE, \ STR_SIZE(DESC, uint16_t)}, @@ -200,7 +203,7 @@ const StaticDiagInfoRec StaticDiagInfo[] = { } // namespace -static const unsigned StaticDiagInfoSize = llvm::array_lengthof(StaticDiagInfo); +static const unsigned StaticDiagInfoSize = std::size(StaticDiagInfo); /// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID, /// or null if the ID is invalid. @@ -253,7 +256,7 @@ CATEGORY(REFACTORING, ANALYSIS) return Found; } -static DiagnosticMapping GetDefaultDiagMapping(unsigned DiagID) { +DiagnosticMapping DiagnosticIDs::getDefaultMapping(unsigned DiagID) { DiagnosticMapping Info = DiagnosticMapping::Make( diag::Severity::Fatal, /*IsUser=*/false, /*IsPragma=*/false); @@ -290,21 +293,6 @@ namespace { }; } -// Unfortunately, the split between DiagnosticIDs and Diagnostic is not -// particularly clean, but for now we just implement this method here so we can -// access GetDefaultDiagMapping. -DiagnosticMapping & -DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) { - std::pair<iterator, bool> Result = - DiagMap.insert(std::make_pair(Diag, DiagnosticMapping())); - - // Initialize the entry if we added it. - if (Result.second) - Result.first->second = GetDefaultDiagMapping(Diag); - - return Result.first->second; -} - static const StaticDiagCategoryRec CategoryNameTable[] = { #define GET_CATEGORY_TABLE #define CATEGORY(X, ENUM) { X, STR_SIZE(X, uint8_t) }, @@ -315,7 +303,7 @@ static const StaticDiagCategoryRec CategoryNameTable[] = { /// getNumberOfCategories - Return the number of categories unsigned DiagnosticIDs::getNumberOfCategories() { - return llvm::array_lengthof(CategoryNameTable) - 1; + return std::size(CategoryNameTable) - 1; } /// getCategoryNameFromID - Given a category ID, return the name of the @@ -446,7 +434,7 @@ bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID, return false; EnabledByDefault = - GetDefaultDiagMapping(DiagID).getSeverity() != diag::Severity::Ignored; + getDefaultMapping(DiagID).getSeverity() != diag::Severity::Ignored; return true; } @@ -454,7 +442,7 @@ bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) { if (DiagID >= diag::DIAG_UPPER_LIMIT) return false; - return GetDefaultDiagMapping(DiagID).getSeverity() >= diag::Severity::Error; + return getDefaultMapping(DiagID).getSeverity() >= diag::Severity::Error; } /// getDescription - Given a diagnostic ID, return a description of the @@ -544,7 +532,7 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, if (Result == diag::Severity::Ignored) return Result; - // Honor -w: this disables all messages which which are not Error/Fatal by + // Honor -w: this disables all messages which are not Error/Fatal by // default (disregarding attempts to upgrade severity from Warning to Error), // as well as disabling all messages which are currently mapped to Warning // (whether by default or downgraded from Error via e.g. -Wno-error or #pragma @@ -586,6 +574,13 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, Diag.getSourceManager().getExpansionLoc(Loc))) return diag::Severity::Ignored; + // We also ignore warnings due to system macros + bool ShowInSystemMacro = + !GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemMacro; + if (State->SuppressSystemWarnings && !ShowInSystemMacro && Loc.isValid() && + Diag.getSourceManager().isInSystemMacro(Loc)) + return diag::Severity::Ignored; + return Result; } @@ -598,6 +593,7 @@ namespace { uint16_t NameOffset; uint16_t Members; uint16_t SubGroups; + StringRef Documentation; // String is stored with a pascal-style length byte. StringRef getName() const { @@ -609,22 +605,47 @@ namespace { // Second the table of options, sorted by name for fast binary lookup. static const WarningOption OptionTable[] = { -#define GET_DIAG_TABLE +#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \ + {FlagNameOffset, Members, SubGroups, Docs}, #include "clang/Basic/DiagnosticGroups.inc" -#undef GET_DIAG_TABLE +#undef DIAG_ENTRY }; +/// Given a diagnostic group ID, return its documentation. +StringRef DiagnosticIDs::getWarningOptionDocumentation(diag::Group Group) { + return OptionTable[static_cast<int>(Group)].Documentation; +} + +StringRef DiagnosticIDs::getWarningOptionForGroup(diag::Group Group) { + return OptionTable[static_cast<int>(Group)].getName(); +} + +std::optional<diag::Group> +DiagnosticIDs::getGroupForWarningOption(StringRef Name) { + const auto *Found = llvm::partition_point( + OptionTable, [=](const WarningOption &O) { return O.getName() < Name; }); + if (Found == std::end(OptionTable) || Found->getName() != Name) + return std::nullopt; + return static_cast<diag::Group>(Found - OptionTable); +} + +std::optional<diag::Group> DiagnosticIDs::getGroupForDiag(unsigned DiagID) { + if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) + return static_cast<diag::Group>(Info->getOptionGroupIndex()); + return std::nullopt; +} + /// getWarningOptionForDiag - Return the lowest-level warning option that /// enables the specified diagnostic. If there is no -Wfoo flag that controls /// the diagnostic, this returns null. StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) { - if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) - return OptionTable[Info->getOptionGroupIndex()].getName(); + if (auto G = getGroupForDiag(DiagID)) + return getWarningOptionForGroup(*G); return StringRef(); } std::vector<std::string> DiagnosticIDs::getDiagnosticFlags() { - std::vector<std::string> Res; + std::vector<std::string> Res{"-W", "-Wno-"}; for (size_t I = 1; DiagGroupNames[I] != '\0';) { std::string Diag(DiagGroupNames + I + 1, DiagGroupNames[I]); I += DiagGroupNames[I] + 1; @@ -668,12 +689,10 @@ static bool getDiagnosticsInGroup(diag::Flavor Flavor, bool DiagnosticIDs::getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group, SmallVectorImpl<diag::kind> &Diags) const { - auto Found = llvm::partition_point( - OptionTable, [=](const WarningOption &O) { return O.getName() < Group; }); - if (Found == std::end(OptionTable) || Found->getName() != Group) - return true; // Option not found. - - return ::getDiagnosticsInGroup(Flavor, Found, Diags); + if (std::optional<diag::Group> G = getGroupForWarningOption(Group)) + return ::getDiagnosticsInGroup( + Flavor, &OptionTable[static_cast<unsigned>(*G)], Diags); + return true; } void DiagnosticIDs::getAllDiagnostics(diag::Flavor Flavor, @@ -686,7 +705,7 @@ void DiagnosticIDs::getAllDiagnostics(diag::Flavor Flavor, StringRef DiagnosticIDs::getNearestOption(diag::Flavor Flavor, StringRef Group) { StringRef Best; - unsigned BestDistance = Group.size() + 1; // Sanity threshold. + unsigned BestDistance = Group.size() + 1; // Maximum threshold. for (const WarningOption &O : OptionTable) { // Don't suggest ignored warning flags. if (!O.Members && !O.SubGroups) @@ -834,5 +853,5 @@ bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const { bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) { unsigned cat = getCategoryNumberForDiag(DiagID); - return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC "); + return DiagnosticIDs::getCategoryNameFromID(cat).starts_with("ARC "); } diff --git a/contrib/llvm-project/clang/lib/Basic/DiagnosticOptions.cpp b/contrib/llvm-project/clang/lib/Basic/DiagnosticOptions.cpp index 68571f2cf94f..12e47ea0231e 100644 --- a/contrib/llvm-project/clang/lib/Basic/DiagnosticOptions.cpp +++ b/contrib/llvm-project/clang/lib/Basic/DiagnosticOptions.cpp @@ -17,7 +17,7 @@ namespace clang { raw_ostream &operator<<(raw_ostream &Out, DiagnosticLevelMask M) { - using UT = std::underlying_type<DiagnosticLevelMask>::type; + using UT = std::underlying_type_t<DiagnosticLevelMask>; return Out << static_cast<UT>(M); } diff --git a/contrib/llvm-project/clang/lib/Basic/FileManager.cpp b/contrib/llvm-project/clang/lib/Basic/FileManager.cpp index 74cd2f295be6..974c8c22598f 100644 --- a/contrib/llvm-project/clang/lib/Basic/FileManager.cpp +++ b/contrib/llvm-project/clang/lib/Basic/FileManager.cpp @@ -31,6 +31,7 @@ #include <climits> #include <cstdint> #include <cstdlib> +#include <optional> #include <string> #include <utility> @@ -105,10 +106,10 @@ void FileManager::addAncestorsAsVirtualDirs(StringRef Path) { return; // Add the virtual directory to the cache. - auto UDE = std::make_unique<DirectoryEntry>(); + auto *UDE = new (DirsAlloc.Allocate()) DirectoryEntry(); UDE->Name = NamedDirEnt.first(); - NamedDirEnt.second = *UDE.get(); - VirtualDirectoryEntries.push_back(std::move(UDE)); + NamedDirEnt.second = *UDE; + VirtualDirectoryEntries.push_back(UDE); // Recursively add the other ancestors. addAncestorsAsVirtualDirs(DirName); @@ -123,16 +124,16 @@ FileManager::getDirectoryRef(StringRef DirName, bool CacheFailure) { DirName != llvm::sys::path::root_path(DirName) && llvm::sys::path::is_separator(DirName.back())) DirName = DirName.substr(0, DirName.size()-1); -#ifdef _WIN32 - // Fixing a problem with "clang C:test.c" on Windows. - // Stat("C:") does not recognize "C:" as a valid directory - std::string DirNameStr; - if (DirName.size() > 1 && DirName.back() == ':' && - DirName.equals_insensitive(llvm::sys::path::root_name(DirName))) { - DirNameStr = DirName.str() + '.'; - DirName = DirNameStr; + std::optional<std::string> DirNameStr; + if (is_style_windows(llvm::sys::path::Style::native)) { + // Fixing a problem with "clang C:test.c" on Windows. + // Stat("C:") does not recognize "C:" as a valid directory + if (DirName.size() > 1 && DirName.back() == ':' && + DirName.equals_insensitive(llvm::sys::path::root_name(DirName))) { + DirNameStr = DirName.str() + '.'; + DirName = *DirNameStr; + } } -#endif ++NumDirLookups; @@ -172,14 +173,15 @@ FileManager::getDirectoryRef(StringRef DirName, bool CacheFailure) { // same inode (this occurs on Unix-like systems when one dir is // symlinked to another, for example) or the same path (on // Windows). - DirectoryEntry &UDE = UniqueRealDirs[Status.getUniqueID()]; + DirectoryEntry *&UDE = UniqueRealDirs[Status.getUniqueID()]; - NamedDirEnt.second = UDE; - if (UDE.getName().empty()) { + if (!UDE) { // We don't have this directory yet, add it. We use the string // key from the SeenDirEntries map as the string. - UDE.Name = InterndDirName; + UDE = new (DirsAlloc.Allocate()) DirectoryEntry(); + UDE->Name = InterndDirName; } + NamedDirEnt.second = *UDE; return DirectoryEntryRef(NamedDirEnt); } @@ -211,13 +213,7 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) { if (!SeenFileInsertResult.first->second) return llvm::errorCodeToError( SeenFileInsertResult.first->second.getError()); - // Construct and return and FileEntryRef, unless it's a redirect to another - // filename. - FileEntryRef::MapValue Value = *SeenFileInsertResult.first->second; - if (LLVM_LIKELY(Value.V.is<FileEntry *>())) - return FileEntryRef(*SeenFileInsertResult.first); - return FileEntryRef(*reinterpret_cast<const FileEntryRef::MapEntry *>( - Value.V.get<const void *>())); + return FileEntryRef(*SeenFileInsertResult.first); } // We've not seen this before. Fill it in. @@ -268,42 +264,77 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) { // It exists. See if we have already opened a file with the same inode. // This occurs when one dir is symlinked to another, for example. - FileEntry &UFE = UniqueRealFiles[Status.getUniqueID()]; - - if (Status.getName() == Filename) { - // The name matches. Set the FileEntry. - NamedFileEnt->second = FileEntryRef::MapValue(UFE, DirInfo); + FileEntry *&UFE = UniqueRealFiles[Status.getUniqueID()]; + bool ReusingEntry = UFE != nullptr; + if (!UFE) + UFE = new (FilesAlloc.Allocate()) FileEntry(); + + if (!Status.ExposesExternalVFSPath || Status.getName() == Filename) { + // Use the requested name. Set the FileEntry. + NamedFileEnt->second = FileEntryRef::MapValue(*UFE, DirInfo); } else { // Name mismatch. We need a redirect. First grab the actual entry we want // to return. + // + // This redirection logic intentionally leaks the external name of a + // redirected file that uses 'use-external-name' in \a + // vfs::RedirectionFileSystem. This allows clang to report the external + // name to users (in diagnostics) and to tools that don't have access to + // the VFS (in debug info and dependency '.d' files). + // + // FIXME: This is pretty complex and has some very complicated interactions + // with the rest of clang. It's also inconsistent with how "real" + // filesystems behave and confuses parts of clang expect to see the + // name-as-accessed on the \a FileEntryRef. + // + // A potential plan to remove this is as follows - + // - Update callers such as `HeaderSearch::findUsableModuleForHeader()` + // to explicitly use the `getNameAsRequested()` rather than just using + // `getName()`. + // - Add a `FileManager::getExternalPath` API for explicitly getting the + // remapped external filename when there is one available. Adopt it in + // callers like diagnostics/deps reporting instead of calling + // `getName()` directly. + // - Switch the meaning of `FileEntryRef::getName()` to get the requested + // name, not the external name. Once that sticks, revert callers that + // want the requested name back to calling `getName()`. + // - Update the VFS to always return the requested name. This could also + // return the external name, or just have an API to request it + // lazily. The latter has the benefit of making accesses of the + // external path easily tracked, but may also require extra work than + // just returning up front. + // - (Optionally) Add an API to VFS to get the external filename lazily + // and update `FileManager::getExternalPath()` to use it instead. This + // has the benefit of making such accesses easily tracked, though isn't + // necessarily required (and could cause extra work than just adding to + // eg. `vfs::Status` up front). auto &Redirection = *SeenFileEntries - .insert({Status.getName(), FileEntryRef::MapValue(UFE, DirInfo)}) + .insert({Status.getName(), FileEntryRef::MapValue(*UFE, DirInfo)}) .first; assert(Redirection.second->V.is<FileEntry *>() && "filename redirected to a non-canonical filename?"); - assert(Redirection.second->V.get<FileEntry *>() == &UFE && + assert(Redirection.second->V.get<FileEntry *>() == UFE && "filename from getStatValue() refers to wrong file"); // Cache the redirection in the previously-inserted entry, still available // in the tentative return value. - NamedFileEnt->second = FileEntryRef::MapValue(Redirection); - - // Fix the tentative return value. - NamedFileEnt = &Redirection; + NamedFileEnt->second = FileEntryRef::MapValue(Redirection, DirInfo); } FileEntryRef ReturnedRef(*NamedFileEnt); - if (UFE.isValid()) { // Already have an entry with this inode, return it. + if (ReusingEntry) { // Already have an entry with this inode, return it. - // FIXME: this hack ensures that if we look up a file by a virtual path in - // the VFS that the getDir() will have the virtual path, even if we found - // the file by a 'real' path first. This is required in order to find a - // module's structure when its headers/module map are mapped in the VFS. - // We should remove this as soon as we can properly support a file having - // multiple names. - if (&DirInfo.getDirEntry() != UFE.Dir && Status.IsVFSMapped) - UFE.Dir = &DirInfo.getDirEntry(); + // FIXME: This hack ensures that `getDir()` will use the path that was + // used to lookup this file, even if we found a file by different path + // first. This is required in order to find a module's structure when its + // headers/module map are mapped in the VFS. + // + // See above for how this will eventually be removed. `IsVFSMapped` + // *cannot* be narrowed to `ExposesExternalVFSPath` as crash reproducers + // also depend on this logic and they have `use-external-paths: false`. + if (&DirInfo.getDirEntry() != UFE->Dir && Status.IsVFSMapped) + UFE->Dir = &DirInfo.getDirEntry(); // Always update LastRef to the last name by which a file was accessed. // FIXME: Neither this nor always using the first reference is correct; we @@ -312,28 +343,27 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) { // corresponding FileEntry. // FIXME: LastRef should be removed from FileEntry once all clients adopt // FileEntryRef. - UFE.LastRef = ReturnedRef; + UFE->LastRef = ReturnedRef; return ReturnedRef; } // Otherwise, we don't have this file yet, add it. - UFE.LastRef = ReturnedRef; - UFE.Size = Status.getSize(); - UFE.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime()); - UFE.Dir = &DirInfo.getDirEntry(); - UFE.UID = NextFileUID++; - UFE.UniqueID = Status.getUniqueID(); - UFE.IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file; - UFE.File = std::move(F); - UFE.IsValid = true; - - if (UFE.File) { - if (auto PathName = UFE.File->getName()) - fillRealPathName(&UFE, *PathName); + UFE->LastRef = ReturnedRef; + UFE->Size = Status.getSize(); + UFE->ModTime = llvm::sys::toTimeT(Status.getLastModificationTime()); + UFE->Dir = &DirInfo.getDirEntry(); + UFE->UID = NextFileUID++; + UFE->UniqueID = Status.getUniqueID(); + UFE->IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file; + UFE->File = std::move(F); + + if (UFE->File) { + if (auto PathName = UFE->File->getName()) + fillRealPathName(UFE, *PathName); } else if (!openFile) { // We should still fill the path even if we aren't opening the file. - fillRealPathName(&UFE, InterndFileName); + fillRealPathName(UFE, InterndFileName); } return ReturnedRef; } @@ -373,8 +403,7 @@ FileEntryRef FileManager::getVirtualFileRef(StringRef Filename, off_t Size, FileEntryRef::MapValue Value = *NamedFileEnt.second; if (LLVM_LIKELY(Value.V.is<FileEntry *>())) return FileEntryRef(NamedFileEnt); - return FileEntryRef(*reinterpret_cast<const FileEntryRef::MapEntry *>( - Value.V.get<const void *>())); + return FileEntryRef(*Value.V.get<const FileEntryRef::MapEntry *>()); } // We've not seen this before, or the file is cached as non-existent. @@ -397,52 +426,55 @@ FileEntryRef FileManager::getVirtualFileRef(StringRef Filename, off_t Size, llvm::vfs::Status Status; const char *InterndFileName = NamedFileEnt.first().data(); if (!getStatValue(InterndFileName, Status, true, nullptr)) { - UFE = &UniqueRealFiles[Status.getUniqueID()]; Status = llvm::vfs::Status( Status.getName(), Status.getUniqueID(), llvm::sys::toTimePoint(ModificationTime), Status.getUser(), Status.getGroup(), Size, Status.getType(), Status.getPermissions()); - NamedFileEnt.second = FileEntryRef::MapValue(*UFE, *DirInfo); - - // If we had already opened this file, close it now so we don't - // leak the descriptor. We're not going to use the file - // descriptor anyway, since this is a virtual file. - if (UFE->File) - UFE->closeFile(); - - // If we already have an entry with this inode, return it. - // - // FIXME: Surely this should add a reference by the new name, and return - // it instead... - if (UFE->isValid()) + auto &RealFE = UniqueRealFiles[Status.getUniqueID()]; + if (RealFE) { + // If we had already opened this file, close it now so we don't + // leak the descriptor. We're not going to use the file + // descriptor anyway, since this is a virtual file. + if (RealFE->File) + RealFE->closeFile(); + // If we already have an entry with this inode, return it. + // + // FIXME: Surely this should add a reference by the new name, and return + // it instead... + NamedFileEnt.second = FileEntryRef::MapValue(*RealFE, *DirInfo); return FileEntryRef(NamedFileEnt); - - UFE->UniqueID = Status.getUniqueID(); - UFE->IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file; - fillRealPathName(UFE, Status.getName()); + } + // File exists, but no entry - create it. + RealFE = new (FilesAlloc.Allocate()) FileEntry(); + RealFE->UniqueID = Status.getUniqueID(); + RealFE->IsNamedPipe = + Status.getType() == llvm::sys::fs::file_type::fifo_file; + fillRealPathName(RealFE, Status.getName()); + + UFE = RealFE; } else { - VirtualFileEntries.push_back(std::make_unique<FileEntry>()); - UFE = VirtualFileEntries.back().get(); - NamedFileEnt.second = FileEntryRef::MapValue(*UFE, *DirInfo); + // File does not exist, create a virtual entry. + UFE = new (FilesAlloc.Allocate()) FileEntry(); + VirtualFileEntries.push_back(UFE); } + NamedFileEnt.second = FileEntryRef::MapValue(*UFE, *DirInfo); UFE->LastRef = FileEntryRef(NamedFileEnt); UFE->Size = Size; UFE->ModTime = ModificationTime; UFE->Dir = &DirInfo->getDirEntry(); UFE->UID = NextFileUID++; - UFE->IsValid = true; UFE->File.reset(); return FileEntryRef(NamedFileEnt); } -llvm::Optional<FileEntryRef> FileManager::getBypassFile(FileEntryRef VF) { +OptionalFileEntryRef FileManager::getBypassFile(FileEntryRef VF) { // Stat of the file and return nullptr if it doesn't exist. llvm::vfs::Status Status; if (getStatValue(VF.getName(), Status, /*isFile=*/true, /*F=*/nullptr)) - return None; + return std::nullopt; if (!SeenBypassFileEntries) SeenBypassFileEntries = std::make_unique< @@ -455,16 +487,14 @@ llvm::Optional<FileEntryRef> FileManager::getBypassFile(FileEntryRef VF) { return FileEntryRef(*Insertion.first); // Fill in the new entry from the stat. - BypassFileEntries.push_back(std::make_unique<FileEntry>()); - const FileEntry &VFE = VF.getFileEntry(); - FileEntry &BFE = *BypassFileEntries.back(); - Insertion.first->second = FileEntryRef::MapValue(BFE, VF.getDir()); - BFE.LastRef = FileEntryRef(*Insertion.first); - BFE.Size = Status.getSize(); - BFE.Dir = VFE.Dir; - BFE.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime()); - BFE.UID = NextFileUID++; - BFE.IsValid = true; + FileEntry *BFE = new (FilesAlloc.Allocate()) FileEntry(); + BypassFileEntries.push_back(BFE); + Insertion.first->second = FileEntryRef::MapValue(*BFE, VF.getDir()); + BFE->LastRef = FileEntryRef(*Insertion.first); + BFE->Size = Status.getSize(); + BFE->Dir = VF.getFileEntry().Dir; + BFE->ModTime = llvm::sys::toTimeT(Status.getLastModificationTime()); + BFE->UID = NextFileUID++; // Save the entry in the bypass table and return. return FileEntryRef(*Insertion.first); @@ -502,12 +532,13 @@ 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 = std::string(AbsPath.str()); + UFE->RealPathName = std::string(AbsPath); } llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> -FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile, +FileManager::getBufferForFile(FileEntryRef FE, bool isVolatile, bool RequiresNullTerminator) { + const FileEntry *Entry = &FE.getFileEntry(); // If the content is living on the file entry, return a reference to it. if (Entry->Content) return llvm::MemoryBuffer::getMemBuffer(Entry->Content->getMemBufferRef()); @@ -518,7 +549,7 @@ FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile, if (isVolatile || Entry->isNamedPipe()) FileSize = -1; - StringRef Filename = Entry->getName(); + StringRef Filename = FE.getName(); // If the file is already open, use the open file descriptor. if (Entry->File) { auto Result = Entry->File->getBuffer(Filename, FileSize, @@ -581,55 +612,66 @@ FileManager::getNoncachedStatValue(StringRef Path, } void FileManager::GetUniqueIDMapping( - SmallVectorImpl<const FileEntry *> &UIDToFiles) const { + SmallVectorImpl<OptionalFileEntryRef> &UIDToFiles) const { UIDToFiles.clear(); UIDToFiles.resize(NextFileUID); - // Map file entries - for (llvm::StringMap<llvm::ErrorOr<FileEntryRef::MapValue>, - llvm::BumpPtrAllocator>::const_iterator - FE = SeenFileEntries.begin(), - FEEnd = SeenFileEntries.end(); - FE != FEEnd; ++FE) - if (llvm::ErrorOr<FileEntryRef::MapValue> Entry = FE->getValue()) { - if (const auto *FE = Entry->V.dyn_cast<FileEntry *>()) - UIDToFiles[FE->getUID()] = FE; - } - - // Map virtual file entries - for (const auto &VFE : VirtualFileEntries) - UIDToFiles[VFE->getUID()] = VFE.get(); + for (const auto &Entry : SeenFileEntries) { + // Only return files that exist and are not redirected. + if (!Entry.getValue() || !Entry.getValue()->V.is<FileEntry *>()) + continue; + FileEntryRef FE(Entry); + // Add this file if it's the first one with the UID, or if its name is + // better than the existing one. + OptionalFileEntryRef &ExistingFE = UIDToFiles[FE.getUID()]; + if (!ExistingFE || FE.getName() < ExistingFE->getName()) + ExistingFE = FE; + } } -StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) { - llvm::DenseMap<const void *, llvm::StringRef>::iterator Known - = CanonicalNames.find(Dir); - if (Known != CanonicalNames.end()) - return Known->second; - - StringRef CanonicalName(Dir->getName()); - - SmallString<4096> CanonicalNameBuf; - if (!FS->getRealPath(Dir->getName(), CanonicalNameBuf)) - CanonicalName = CanonicalNameBuf.str().copy(CanonicalNameStorage); +StringRef FileManager::getCanonicalName(DirectoryEntryRef Dir) { + return getCanonicalName(Dir, Dir.getName()); +} - CanonicalNames.insert({Dir, CanonicalName}); - return CanonicalName; +StringRef FileManager::getCanonicalName(FileEntryRef File) { + return getCanonicalName(File, File.getName()); } -StringRef FileManager::getCanonicalName(const FileEntry *File) { - llvm::DenseMap<const void *, llvm::StringRef>::iterator Known - = CanonicalNames.find(File); +StringRef FileManager::getCanonicalName(const void *Entry, StringRef Name) { + llvm::DenseMap<const void *, llvm::StringRef>::iterator Known = + CanonicalNames.find(Entry); if (Known != CanonicalNames.end()) return Known->second; - StringRef CanonicalName(File->getName()); - - SmallString<4096> CanonicalNameBuf; - if (!FS->getRealPath(File->getName(), CanonicalNameBuf)) - CanonicalName = CanonicalNameBuf.str().copy(CanonicalNameStorage); + // Name comes from FileEntry/DirectoryEntry::getName(), so it is safe to + // store it in the DenseMap below. + StringRef CanonicalName(Name); + + SmallString<256> AbsPathBuf; + SmallString<256> RealPathBuf; + if (!FS->getRealPath(Name, RealPathBuf)) { + if (is_style_windows(llvm::sys::path::Style::native)) { + // For Windows paths, only use the real path if it doesn't resolve + // a substitute drive, as those are used to avoid MAX_PATH issues. + AbsPathBuf = Name; + if (!FS->makeAbsolute(AbsPathBuf)) { + if (llvm::sys::path::root_name(RealPathBuf) == + llvm::sys::path::root_name(AbsPathBuf)) { + CanonicalName = RealPathBuf.str().copy(CanonicalNameStorage); + } else { + // Fallback to using the absolute path. + // Simplifying /../ is semantically valid on Windows even in the + // presence of symbolic links. + llvm::sys::path::remove_dots(AbsPathBuf, /*remove_dot_dot=*/true); + CanonicalName = AbsPathBuf.str().copy(CanonicalNameStorage); + } + } + } else { + CanonicalName = RealPathBuf.str().copy(CanonicalNameStorage); + } + } - CanonicalNames.insert({File, CanonicalName}); + CanonicalNames.insert({Entry, CanonicalName}); return CanonicalName; } diff --git a/contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp b/contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp index d811aeec84a0..d0d8316385b4 100644 --- a/contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp +++ b/contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp @@ -13,6 +13,7 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/Specifiers.h" @@ -24,7 +25,6 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include <cassert> #include <cstdio> @@ -51,8 +51,7 @@ namespace { /// A simple identifier lookup iterator that represents an /// empty sequence of identifiers. -class EmptyLookupIterator : public IdentifierIterator -{ +class EmptyLookupIterator : public IdentifierIterator { public: StringRef Next() override { return StringRef(); } }; @@ -82,7 +81,7 @@ IdentifierTable::IdentifierTable(const LangOptions &LangOpts, // Constants for TokenKinds.def namespace { - enum { + enum TokenKey : unsigned { KEYC99 = 0x1, KEYCXX = 0x2, KEYCXX11 = 0x4, @@ -93,72 +92,158 @@ namespace { KEYNOCXX = 0x80, KEYBORLAND = 0x100, KEYOPENCLC = 0x200, - KEYC11 = 0x400, + KEYC23 = 0x400, KEYNOMS18 = 0x800, KEYNOOPENCL = 0x1000, WCHARSUPPORT = 0x2000, HALFSUPPORT = 0x4000, CHAR8SUPPORT = 0x8000, - KEYCONCEPTS = 0x10000, - KEYOBJC = 0x20000, - KEYZVECTOR = 0x40000, - KEYCOROUTINES = 0x80000, - KEYMODULES = 0x100000, - KEYCXX20 = 0x200000, - KEYOPENCLCXX = 0x400000, - KEYMSCOMPAT = 0x800000, - KEYSYCL = 0x1000000, + KEYOBJC = 0x10000, + KEYZVECTOR = 0x20000, + KEYCOROUTINES = 0x40000, + KEYMODULES = 0x80000, + KEYCXX20 = 0x100000, + KEYOPENCLCXX = 0x200000, + KEYMSCOMPAT = 0x400000, + KEYSYCL = 0x800000, + KEYCUDA = 0x1000000, + KEYHLSL = 0x2000000, + KEYFIXEDPOINT = 0x4000000, + KEYMAX = KEYFIXEDPOINT, // The maximum key KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX20, - KEYALL = (0x1ffffff & ~KEYNOMS18 & - ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude. + KEYALL = (KEYMAX | (KEYMAX-1)) & ~KEYNOMS18 & + ~KEYNOOPENCL // KEYNOMS18 and KEYNOOPENCL are used to exclude. }; - /// How a keyword is treated in the selected standard. + /// How a keyword is treated in the selected standard. This enum is ordered + /// intentionally so that the value that 'wins' is the most 'permissive'. enum KeywordStatus { + KS_Unknown, // Not yet calculated. Used when figuring out the status. KS_Disabled, // Disabled + KS_Future, // Is a keyword in future standard KS_Extension, // Is an extension KS_Enabled, // Enabled - KS_Future // Is a keyword in future standard }; } // namespace +// This works on a single TokenKey flag and checks the LangOpts to get the +// KeywordStatus based exclusively on this flag, so that it can be merged in +// getKeywordStatus. Most should be enabled/disabled, but some might imply +// 'future' versions, or extensions. Returns 'unknown' unless this is KNOWN to +// be disabled, and the calling function makes it 'disabled' if no other flag +// changes it. This is necessary for the KEYNOCXX and KEYNOOPENCL flags. +static KeywordStatus getKeywordStatusHelper(const LangOptions &LangOpts, + TokenKey Flag) { + // Flag is a single bit version of TokenKey (that is, not + // KEYALL/KEYALLCXX/etc), so we can check with == throughout this function. + assert((Flag & ~(Flag - 1)) == Flag && "Multiple bits set?"); + + switch (Flag) { + case KEYC99: + if (LangOpts.C99) + return KS_Enabled; + return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown; + case KEYC23: + if (LangOpts.C23) + return KS_Enabled; + return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown; + case KEYCXX: + return LangOpts.CPlusPlus ? KS_Enabled : KS_Unknown; + case KEYCXX11: + if (LangOpts.CPlusPlus11) + return KS_Enabled; + return LangOpts.CPlusPlus ? KS_Future : KS_Unknown; + case KEYCXX20: + if (LangOpts.CPlusPlus20) + return KS_Enabled; + return LangOpts.CPlusPlus ? KS_Future : KS_Unknown; + case KEYGNU: + return LangOpts.GNUKeywords ? KS_Extension : KS_Unknown; + case KEYMS: + return LangOpts.MicrosoftExt ? KS_Extension : KS_Unknown; + case BOOLSUPPORT: + if (LangOpts.Bool) return KS_Enabled; + return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown; + case KEYALTIVEC: + return LangOpts.AltiVec ? KS_Enabled : KS_Unknown; + case KEYBORLAND: + return LangOpts.Borland ? KS_Extension : KS_Unknown; + case KEYOPENCLC: + return LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus ? KS_Enabled + : KS_Unknown; + case WCHARSUPPORT: + return LangOpts.WChar ? KS_Enabled : KS_Unknown; + case HALFSUPPORT: + return LangOpts.Half ? KS_Enabled : KS_Unknown; + case CHAR8SUPPORT: + if (LangOpts.Char8) return KS_Enabled; + if (LangOpts.CPlusPlus20) return KS_Unknown; + if (LangOpts.CPlusPlus) return KS_Future; + return KS_Unknown; + case KEYOBJC: + // We treat bridge casts as objective-C keywords so we can warn on them + // in non-arc mode. + return LangOpts.ObjC ? KS_Enabled : KS_Unknown; + case KEYZVECTOR: + return LangOpts.ZVector ? KS_Enabled : KS_Unknown; + case KEYCOROUTINES: + return LangOpts.Coroutines ? KS_Enabled : KS_Unknown; + case KEYMODULES: + return KS_Unknown; + case KEYOPENCLCXX: + return LangOpts.OpenCLCPlusPlus ? KS_Enabled : KS_Unknown; + case KEYMSCOMPAT: + return LangOpts.MSVCCompat ? KS_Enabled : KS_Unknown; + case KEYSYCL: + return LangOpts.isSYCL() ? KS_Enabled : KS_Unknown; + case KEYCUDA: + return LangOpts.CUDA ? KS_Enabled : KS_Unknown; + case KEYHLSL: + return LangOpts.HLSL ? KS_Enabled : KS_Unknown; + case KEYNOCXX: + // This is enabled in all non-C++ modes, but might be enabled for other + // reasons as well. + return LangOpts.CPlusPlus ? KS_Unknown : KS_Enabled; + case KEYNOOPENCL: + // The disable behavior for this is handled in getKeywordStatus. + return KS_Unknown; + case KEYNOMS18: + // The disable behavior for this is handled in getKeywordStatus. + return KS_Unknown; + case KEYFIXEDPOINT: + return LangOpts.FixedPoint ? KS_Enabled : KS_Disabled; + default: + llvm_unreachable("Unknown KeywordStatus flag"); + } +} + /// Translates flags as specified in TokenKinds.def into keyword status /// in the given language standard. static KeywordStatus getKeywordStatus(const LangOptions &LangOpts, unsigned Flags) { + // KEYALL means always enabled, so special case this one. if (Flags == KEYALL) return KS_Enabled; - if (LangOpts.CPlusPlus && (Flags & KEYCXX)) return KS_Enabled; - if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11)) 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; - if (LangOpts.MSVCCompat && (Flags & KEYMSCOMPAT)) return KS_Enabled; - if (LangOpts.Borland && (Flags & KEYBORLAND)) return KS_Extension; - if (LangOpts.Bool && (Flags & BOOLSUPPORT)) return KS_Enabled; - if (LangOpts.Half && (Flags & HALFSUPPORT)) return KS_Enabled; - if (LangOpts.WChar && (Flags & WCHARSUPPORT)) return KS_Enabled; - if (LangOpts.Char8 && (Flags & CHAR8SUPPORT)) return KS_Enabled; - if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) return KS_Enabled; - if (LangOpts.ZVector && (Flags & KEYZVECTOR)) return KS_Enabled; - if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus && (Flags & KEYOPENCLC)) - return KS_Enabled; - if (LangOpts.OpenCLCPlusPlus && (Flags & KEYOPENCLCXX)) return KS_Enabled; - if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) return KS_Enabled; - if (LangOpts.C11 && (Flags & KEYC11)) return KS_Enabled; - // 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.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; - if (LangOpts.isSYCL() && (Flags & KEYSYCL)) - return KS_Enabled; - return KS_Disabled; + // These are tests that need to 'always win', as they are special in that they + // disable based on certain conditions. + if (LangOpts.OpenCL && (Flags & KEYNOOPENCL)) return KS_Disabled; + if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) && + !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015)) + return KS_Disabled; + + KeywordStatus CurStatus = KS_Unknown; + + while (Flags != 0) { + unsigned CurFlag = Flags & ~(Flags - 1); + Flags = Flags & ~CurFlag; + CurStatus = std::max( + CurStatus, + getKeywordStatusHelper(LangOpts, static_cast<TokenKey>(CurFlag))); + } + + if (CurStatus == KS_Unknown) + return KS_Disabled; + return CurStatus; } /// AddKeyword - This method is used to associate a token ID with specific @@ -169,15 +254,6 @@ static void AddKeyword(StringRef Keyword, const LangOptions &LangOpts, IdentifierTable &Table) { KeywordStatus AddResult = getKeywordStatus(LangOpts, Flags); - // Don't add this keyword under MSVCCompat. - if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) && - !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015)) - return; - - // Don't add this keyword under OpenCL. - if (LangOpts.OpenCL && (Flags & KEYNOOPENCL)) - return; - // Don't add this keyword if disabled in this language. if (AddResult == KS_Disabled) return; @@ -204,6 +280,16 @@ static void AddObjCKeyword(StringRef Name, Table.get(Name).setObjCKeywordID(ObjCID); } +static void AddInterestingIdentifier(StringRef Name, + tok::InterestingIdentifierKind BTID, + IdentifierTable &Table) { + // Don't add 'not_interesting' identifier. + if (BTID != tok::not_interesting) { + IdentifierInfo &Info = Table.get(Name, tok::identifier); + Info.setInterestingIdentifierID(BTID); + } +} + /// AddKeywords - Add all keywords to the symbol table. /// void IdentifierTable::AddKeywords(const LangOptions &LangOpts) { @@ -220,6 +306,9 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) { #define OBJC_AT_KEYWORD(NAME) \ if (LangOpts.ObjC) \ AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this); +#define INTERESTING_IDENTIFIER(NAME) \ + AddInterestingIdentifier(StringRef(#NAME), tok::NAME, *this); + #define TESTING_KEYWORD(NAME, FLAGS) #include "clang/Basic/TokenKinds.def" @@ -309,6 +398,27 @@ IdentifierInfo::isReserved(const LangOptions &LangOpts) const { return ReservedIdentifierStatus::NotReserved; } +ReservedLiteralSuffixIdStatus +IdentifierInfo::isReservedLiteralSuffixId() const { + StringRef Name = getName(); + + if (Name[0] != '_') + return ReservedLiteralSuffixIdStatus::NotStartsWithUnderscore; + + if (Name.contains("__")) + return ReservedLiteralSuffixIdStatus::ContainsDoubleUnderscore; + + return ReservedLiteralSuffixIdStatus::NotReserved; +} + +StringRef IdentifierInfo::deuglifiedName() const { + StringRef Name = getName(); + if (Name.size() >= 2 && Name.front() == '_' && + (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z'))) + return Name.ltrim('_'); + return Name; +} + tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const { // We use a perfect hash function here involving the length of the keyword, // the first and third character. For preprocessor ID's there are no @@ -405,63 +515,6 @@ unsigned llvm::DenseMapInfo<clang::Selector>::getHashValue(clang::Selector S) { return DenseMapInfo<void*>::getHashValue(S.getAsOpaquePtr()); } -namespace clang { - -/// One of these variable length records is kept for each -/// selector containing more than one keyword. We use a folding set -/// to unique aggregate names (keyword selectors in ObjC parlance). Access to -/// this class is provided strictly through Selector. -class alignas(IdentifierInfoAlignment) MultiKeywordSelector - : public detail::DeclarationNameExtra, - public llvm::FoldingSetNode { - MultiKeywordSelector(unsigned nKeys) : DeclarationNameExtra(nKeys) {} - -public: - // Constructor for keyword selectors. - MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) - : DeclarationNameExtra(nKeys) { - assert((nKeys > 1) && "not a multi-keyword selector"); - - // Fill in the trailing keyword array. - IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this + 1); - for (unsigned i = 0; i != nKeys; ++i) - KeyInfo[i] = IIV[i]; - } - - // getName - Derive the full selector name and return it. - std::string getName() const; - - using DeclarationNameExtra::getNumArgs; - - using keyword_iterator = IdentifierInfo *const *; - - keyword_iterator keyword_begin() const { - return reinterpret_cast<keyword_iterator>(this + 1); - } - - keyword_iterator keyword_end() const { - return keyword_begin() + getNumArgs(); - } - - IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const { - assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index"); - return keyword_begin()[i]; - } - - static void Profile(llvm::FoldingSetNodeID &ID, keyword_iterator ArgTys, - unsigned NumArgs) { - ID.AddInteger(NumArgs); - for (unsigned i = 0; i != NumArgs; ++i) - ID.AddPointer(ArgTys[i]); - } - - void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, keyword_begin(), getNumArgs()); - } -}; - -} // namespace clang. - bool Selector::isKeywordSelector(ArrayRef<StringRef> Names) const { assert(!Names.empty() && "must have >= 1 selector slots"); if (getNumArgs() != Names.size()) @@ -517,7 +570,7 @@ std::string MultiKeywordSelector::getName() const { } std::string Selector::getAsString() const { - if (InfoPtr == 0) + if (isNull()) return "<null selector>"; if (getIdentifierInfoFlag() < MultiArg) { @@ -551,7 +604,7 @@ LLVM_DUMP_METHOD void Selector::dump() const { print(llvm::errs()); } static bool startsWithWord(StringRef name, StringRef word) { if (name.size() < word.size()) return false; return ((name.size() == word.size() || !isLowercase(name[word.size()])) && - name.startswith(word)); + name.starts_with(word)); } ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) { @@ -575,8 +628,7 @@ ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) { return OMF_performSelector; // The other method families may begin with a prefix of underscores. - while (!name.empty() && name.front() == '_') - name = name.substr(1); + name = name.ltrim('_'); if (name.empty()) return OMF_None; switch (name.front()) { @@ -689,7 +741,7 @@ SelectorTable::constructSetterSelector(IdentifierTable &Idents, std::string SelectorTable::getPropertyNameFromSetterSelector(Selector Sel) { StringRef Name = Sel.getNameForSlot(0); - assert(Name.startswith("set") && "invalid setter name"); + assert(Name.starts_with("set") && "invalid setter name"); return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str(); } @@ -765,3 +817,50 @@ StringRef clang::getNullabilitySpelling(NullabilityKind kind, } llvm_unreachable("Unknown nullability kind."); } + +llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS, + NullabilityKind NK) { + switch (NK) { + case NullabilityKind::NonNull: + return OS << "NonNull"; + case NullabilityKind::Nullable: + return OS << "Nullable"; + case NullabilityKind::NullableResult: + return OS << "NullableResult"; + case NullabilityKind::Unspecified: + return OS << "Unspecified"; + } + llvm_unreachable("Unknown nullability kind."); +} + +diag::kind +IdentifierTable::getFutureCompatDiagKind(const IdentifierInfo &II, + const LangOptions &LangOpts) { + assert(II.isFutureCompatKeyword() && "diagnostic should not be needed"); + + unsigned Flags = llvm::StringSwitch<unsigned>(II.getName()) +#define KEYWORD(NAME, FLAGS) .Case(#NAME, FLAGS) +#include "clang/Basic/TokenKinds.def" +#undef KEYWORD + ; + + if (LangOpts.CPlusPlus) { + if ((Flags & KEYCXX11) == KEYCXX11) + return diag::warn_cxx11_keyword; + + // char8_t is not modeled as a CXX20_KEYWORD because it's not + // unconditionally enabled in C++20 mode. (It can be disabled + // by -fno-char8_t.) + if (((Flags & KEYCXX20) == KEYCXX20) || + ((Flags & CHAR8SUPPORT) == CHAR8SUPPORT)) + return diag::warn_cxx20_keyword; + } else { + if ((Flags & KEYC99) == KEYC99) + return diag::warn_c99_keyword; + if ((Flags & KEYC23) == KEYC23) + return diag::warn_c23_keyword; + } + + llvm_unreachable( + "Keyword not known to come from a newer Standard or proposed Standard"); +} diff --git a/contrib/llvm-project/clang/lib/Basic/LangOptions.cpp b/contrib/llvm-project/clang/lib/Basic/LangOptions.cpp index bebf3178426f..a0adfbf61840 100644 --- a/contrib/llvm-project/clang/lib/Basic/LangOptions.cpp +++ b/contrib/llvm-project/clang/lib/Basic/LangOptions.cpp @@ -29,6 +29,14 @@ void LangOptions::resetNonModularOptions() { Name = static_cast<unsigned>(Default); #include "clang/Basic/LangOptions.def" + // Reset "benign" options with implied values (Options.td ImpliedBy relations) + // rather than their defaults. This avoids unexpected combinations and + // invocations that cannot be round-tripped to arguments. + // FIXME: we should derive this automatically from ImpliedBy in tablegen. + AllowFPReassoc = UnsafeFPMath; + NoHonorNaNs = FiniteMathOnly; + NoHonorInfs = FiniteMathOnly; + // These options do not affect AST generation. NoSanitizeFiles.clear(); XRayAlwaysInstrumentFiles.clear(); @@ -47,20 +55,173 @@ bool LangOptions::isNoBuiltinFunc(StringRef FuncName) const { VersionTuple LangOptions::getOpenCLVersionTuple() const { const int Ver = OpenCLCPlusPlus ? OpenCLCPlusPlusVersion : OpenCLVersion; + if (OpenCLCPlusPlus && Ver != 100) + return VersionTuple(Ver / 100); return VersionTuple(Ver / 100, (Ver % 100) / 10); } -void LangOptions::remapPathPrefix(SmallString<256> &Path) const { +unsigned LangOptions::getOpenCLCompatibleVersion() const { + if (!OpenCLCPlusPlus) + return OpenCLVersion; + if (OpenCLCPlusPlusVersion == 100) + return 200; + if (OpenCLCPlusPlusVersion == 202100) + return 300; + llvm_unreachable("Unknown OpenCL version"); +} + +void LangOptions::remapPathPrefix(SmallVectorImpl<char> &Path) const { for (const auto &Entry : MacroPrefixMap) if (llvm::sys::path::replace_path_prefix(Path, Entry.first, Entry.second)) break; } +std::string LangOptions::getOpenCLVersionString() const { + std::string Result; + { + llvm::raw_string_ostream Out(Result); + Out << (OpenCLCPlusPlus ? "C++ for OpenCL" : "OpenCL C") << " version " + << getOpenCLVersionTuple().getAsString(); + } + return Result; +} + +void LangOptions::setLangDefaults(LangOptions &Opts, Language Lang, + const llvm::Triple &T, + std::vector<std::string> &Includes, + LangStandard::Kind LangStd) { + // Set some properties which depend solely on the input kind; it would be nice + // to move these to the language standard, and have the driver resolve the + // input kind + language standard. + // + // FIXME: Perhaps a better model would be for a single source file to have + // multiple language standards (C / C++ std, ObjC std, OpenCL std, OpenMP std) + // simultaneously active? + if (Lang == Language::Asm) { + Opts.AsmPreprocessor = 1; + } else if (Lang == Language::ObjC || Lang == Language::ObjCXX) { + Opts.ObjC = 1; + } + + if (LangStd == LangStandard::lang_unspecified) + LangStd = getDefaultLanguageStandard(Lang, T); + const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); + Opts.LangStd = LangStd; + Opts.LineComment = Std.hasLineComments(); + Opts.C99 = Std.isC99(); + Opts.C11 = Std.isC11(); + Opts.C17 = Std.isC17(); + Opts.C23 = Std.isC23(); + Opts.CPlusPlus = Std.isCPlusPlus(); + Opts.CPlusPlus11 = Std.isCPlusPlus11(); + Opts.CPlusPlus14 = Std.isCPlusPlus14(); + Opts.CPlusPlus17 = Std.isCPlusPlus17(); + Opts.CPlusPlus20 = Std.isCPlusPlus20(); + Opts.CPlusPlus23 = Std.isCPlusPlus23(); + Opts.CPlusPlus26 = Std.isCPlusPlus26(); + Opts.GNUMode = Std.isGNUMode(); + Opts.GNUCVersion = 0; + Opts.HexFloats = Std.hasHexFloats(); + Opts.WChar = Std.isCPlusPlus(); + Opts.Digraphs = Std.hasDigraphs(); + + Opts.HLSL = Lang == Language::HLSL; + if (Opts.HLSL && Opts.IncludeDefaultHeader) + Includes.push_back("hlsl.h"); + + // Set OpenCL Version. + Opts.OpenCL = Std.isOpenCL(); + if (LangStd == LangStandard::lang_opencl10) + Opts.OpenCLVersion = 100; + else if (LangStd == LangStandard::lang_opencl11) + Opts.OpenCLVersion = 110; + else if (LangStd == LangStandard::lang_opencl12) + Opts.OpenCLVersion = 120; + else if (LangStd == LangStandard::lang_opencl20) + Opts.OpenCLVersion = 200; + else if (LangStd == LangStandard::lang_opencl30) + Opts.OpenCLVersion = 300; + else if (LangStd == LangStandard::lang_openclcpp10) + Opts.OpenCLCPlusPlusVersion = 100; + else if (LangStd == LangStandard::lang_openclcpp2021) + Opts.OpenCLCPlusPlusVersion = 202100; + else if (LangStd == LangStandard::lang_hlsl2015) + Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2015; + else if (LangStd == LangStandard::lang_hlsl2016) + Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2016; + else if (LangStd == LangStandard::lang_hlsl2017) + Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2017; + else if (LangStd == LangStandard::lang_hlsl2018) + Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2018; + else if (LangStd == LangStandard::lang_hlsl2021) + Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2021; + else if (LangStd == LangStandard::lang_hlsl202x) + Opts.HLSLVersion = (unsigned)LangOptions::HLSL_202x; + + // OpenCL has some additional defaults. + if (Opts.OpenCL) { + Opts.AltiVec = 0; + Opts.ZVector = 0; + Opts.setDefaultFPContractMode(LangOptions::FPM_On); + Opts.OpenCLCPlusPlus = Opts.CPlusPlus; + Opts.OpenCLPipes = Opts.getOpenCLCompatibleVersion() == 200; + Opts.OpenCLGenericAddressSpace = Opts.getOpenCLCompatibleVersion() == 200; + + // Include default header file for OpenCL. + if (Opts.IncludeDefaultHeader) { + if (Opts.DeclareOpenCLBuiltins) { + // Only include base header file for builtin types and constants. + Includes.push_back("opencl-c-base.h"); + } else { + Includes.push_back("opencl-c.h"); + } + } + } + + Opts.HIP = Lang == Language::HIP; + Opts.CUDA = Lang == Language::CUDA || Opts.HIP; + if (Opts.HIP) { + // HIP toolchain does not support 'Fast' FPOpFusion in backends since it + // fuses multiplication/addition instructions without contract flag from + // device library functions in LLVM bitcode, which causes accuracy loss in + // certain math functions, e.g. tan(-1e20) becomes -0.933 instead of 0.8446. + // For device library functions in bitcode to work, 'Strict' or 'Standard' + // FPOpFusion options in backends is needed. Therefore 'fast-honor-pragmas' + // FP contract option is used to allow fuse across statements in frontend + // whereas respecting contract flag in backend. + Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas); + } else if (Opts.CUDA) { + if (T.isSPIRV()) { + // Emit OpenCL version metadata in LLVM IR when targeting SPIR-V. + Opts.OpenCLVersion = 200; + } + // Allow fuse across statements disregarding pragmas. + Opts.setDefaultFPContractMode(LangOptions::FPM_Fast); + } + + Opts.RenderScript = Lang == Language::RenderScript; + + // OpenCL, C++ and C23 have bool, true, false keywords. + Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C23; + + // OpenCL and HLSL have half keyword + Opts.Half = Opts.OpenCL || Opts.HLSL; +} + FPOptions FPOptions::defaultWithoutTrailingStorage(const LangOptions &LO) { FPOptions result(LO); return result; } +FPOptionsOverride FPOptions::getChangesSlow(const FPOptions &Base) const { + FPOptions::storage_type OverrideMask = 0; +#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ + if (get##NAME() != Base.get##NAME()) \ + OverrideMask |= NAME##Mask; +#include "clang/Basic/FPOptions.def" + return FPOptionsOverride(*this, OverrideMask); +} + LLVM_DUMP_METHOD void FPOptions::dump() { #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ llvm::errs() << "\n " #NAME " " << get##NAME(); diff --git a/contrib/llvm-project/clang/lib/Basic/LangStandards.cpp b/contrib/llvm-project/clang/lib/Basic/LangStandards.cpp index ee27bfd12113..ab09c7221dda 100644 --- a/contrib/llvm-project/clang/lib/Basic/LangStandards.cpp +++ b/contrib/llvm-project/clang/lib/Basic/LangStandards.cpp @@ -7,10 +7,45 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/LangStandard.h" +#include "clang/Config/config.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/TargetParser/Triple.h" using namespace clang; +StringRef clang::languageToString(Language L) { + switch (L) { + case Language::Unknown: + return "Unknown"; + case Language::Asm: + return "Asm"; + case Language::LLVM_IR: + return "LLVM IR"; + case Language::C: + return "C"; + case Language::CXX: + return "C++"; + case Language::ObjC: + return "Objective-C"; + case Language::ObjCXX: + return "Objective-C++"; + case Language::OpenCL: + return "OpenCL"; + case Language::OpenCLCXX: + return "OpenCLC++"; + case Language::CUDA: + return "CUDA"; + case Language::RenderScript: + return "RenderScript"; + case Language::HIP: + return "HIP"; + case Language::HLSL: + return "HLSL"; + } + + llvm_unreachable("unhandled language kind"); +} + #define LANGSTANDARD(id, name, lang, desc, features) \ static const LangStandard Lang_##id = {name, desc, features, Language::lang}; #include "clang/Basic/LangStandards.def" @@ -42,4 +77,33 @@ const LangStandard *LangStandard::getLangStandardForName(StringRef Name) { return &getLangStandardForKind(K); } - +LangStandard::Kind clang::getDefaultLanguageStandard(clang::Language Lang, + const llvm::Triple &T) { + switch (Lang) { + case Language::Unknown: + case Language::LLVM_IR: + llvm_unreachable("Invalid input kind!"); + case Language::OpenCL: + return LangStandard::lang_opencl12; + case Language::OpenCLCXX: + return LangStandard::lang_openclcpp10; + case Language::Asm: + case Language::C: + // The PS4 uses C99 as the default C standard. + if (T.isPS4()) + return LangStandard::lang_gnu99; + return LangStandard::lang_gnu17; + case Language::ObjC: + return LangStandard::lang_gnu11; + case Language::CXX: + case Language::ObjCXX: + case Language::CUDA: + case Language::HIP: + return LangStandard::lang_gnucxx17; + case Language::RenderScript: + return LangStandard::lang_c99; + case Language::HLSL: + return LangStandard::lang_hlsl2021; + } + llvm_unreachable("unhandled Language kind!"); +} diff --git a/contrib/llvm-project/clang/lib/Basic/MakeSupport.cpp b/contrib/llvm-project/clang/lib/Basic/MakeSupport.cpp new file mode 100644 index 000000000000..4ddfcc350410 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Basic/MakeSupport.cpp @@ -0,0 +1,35 @@ +//===-- MakeSuport.cpp --------------------------------------------------*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/MakeSupport.h" + +void clang::quoteMakeTarget(StringRef Target, SmallVectorImpl<char> &Res) { + for (unsigned i = 0, e = Target.size(); i != e; ++i) { + switch (Target[i]) { + case ' ': + case '\t': + // Escape the preceding backslashes + for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j) + Res.push_back('\\'); + + // Escape the space/tab + Res.push_back('\\'); + break; + case '$': + Res.push_back('$'); + break; + case '#': + Res.push_back('\\'); + break; + default: + break; + } + + Res.push_back(Target[i]); + } +} diff --git a/contrib/llvm-project/clang/lib/Basic/Module.cpp b/contrib/llvm-project/clang/lib/Basic/Module.cpp index b6cf1624ef01..0dac8748a98a 100644 --- a/contrib/llvm-project/clang/lib/Basic/Module.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Module.cpp @@ -44,7 +44,7 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, InferSubmodules(false), InferExplicitSubmodules(false), InferExportWildcard(false), ConfigMacrosExhaustive(false), NoUndeclaredIncludes(false), ModuleMapIsPrivate(false), - NameVisibility(Hidden) { + NamedModuleHasInit(true), NameVisibility(Hidden) { if (Parent) { IsAvailable = Parent->isAvailable(); IsUnimportable = Parent->isUnimportable(); @@ -59,9 +59,8 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, } Module::~Module() { - for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); - I != IEnd; ++I) { - delete *I; + for (auto *Submodule : SubModules) { + delete Submodule; } } @@ -90,7 +89,7 @@ static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) { // where both are valid examples of the same platform+environment but in the // variant (2) the simulator is hardcoded as part of the platform name. Both // forms above should match for "iossimulator" requirement. - if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator")) + if (Target.getTriple().isOSDarwin() && PlatformEnv.ends_with("simulator")) return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature); return PlatformEnv == Feature; @@ -108,9 +107,13 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, .Case("cplusplus11", LangOpts.CPlusPlus11) .Case("cplusplus14", LangOpts.CPlusPlus14) .Case("cplusplus17", LangOpts.CPlusPlus17) + .Case("cplusplus20", LangOpts.CPlusPlus20) + .Case("cplusplus23", LangOpts.CPlusPlus23) + .Case("cplusplus26", LangOpts.CPlusPlus26) .Case("c99", LangOpts.C99) .Case("c11", LangOpts.C11) .Case("c17", LangOpts.C17) + .Case("c23", LangOpts.C23) .Case("freestanding", LangOpts.Freestanding) .Case("gnuinlineasm", LangOpts.GNUAsm) .Case("objc", LangOpts.ObjC) @@ -121,9 +124,7 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, .Default(Target.hasFeature(Feature) || isPlatformEnvironment(Target, Feature)); if (!HasFeature) - HasFeature = std::find(LangOpts.ModuleFeatures.begin(), - LangOpts.ModuleFeatures.end(), - Feature) != LangOpts.ModuleFeatures.end(); + HasFeature = llvm::is_contained(LangOpts.ModuleFeatures, Feature); return HasFeature; } @@ -150,6 +151,28 @@ bool Module::isUnimportable(const LangOptions &LangOpts, llvm_unreachable("could not find a reason why module is unimportable"); } +// The -fmodule-name option tells the compiler to textually include headers in +// the specified module, meaning Clang won't build the specified module. This +// is useful in a number of situations, for instance, when building a library +// that vends a module map, one might want to avoid hitting intermediate build +// products containing the module map or avoid finding the system installed +// modulemap for that library. +bool Module::isForBuilding(const LangOptions &LangOpts) const { + StringRef TopLevelName = getTopLevelModuleName(); + StringRef CurrentModule = LangOpts.CurrentModule; + + // When building the implementation of framework Foo, we want to make sure + // that Foo *and* Foo_Private are textually included and no modules are built + // for either. + if (!LangOpts.isCompilingModule() && getTopLevelModule()->IsFramework && + CurrentModule == LangOpts.ModuleName && + !CurrentModule.ends_with("_Private") && + TopLevelName.ends_with("_Private")) + TopLevelName = TopLevelName.drop_back(8); + + return TopLevelName == CurrentModule; +} + bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, Requirement &Req, UnresolvedHeaderDirective &MissingHeader, @@ -203,7 +226,7 @@ static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, OS << "."; StringRef Name = getModuleNameFromComponent(*It); - if (!AllowStringLiterals || isValidIdentifier(Name)) + if (!AllowStringLiterals || isValidAsciiIdentifier(Name)) OS << Name; else { OS << '"'; @@ -243,33 +266,31 @@ bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { return nameParts.empty(); } -Module::DirectoryName Module::getUmbrellaDir() const { - if (Header U = getUmbrellaHeader()) - return {"", "", U.Entry->getDir()}; - - return {UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory, - Umbrella.dyn_cast<const DirectoryEntry *>()}; +OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const { + if (const auto *Hdr = std::get_if<FileEntryRef>(&Umbrella)) + return Hdr->getDir(); + if (const auto *Dir = std::get_if<DirectoryEntryRef>(&Umbrella)) + return *Dir; + return std::nullopt; } -void Module::addTopHeader(const FileEntry *File) { +void Module::addTopHeader(FileEntryRef File) { assert(File); TopHeaders.insert(File); } -ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { +ArrayRef<FileEntryRef> Module::getTopHeaders(FileManager &FileMgr) { if (!TopHeaderNames.empty()) { - for (std::vector<std::string>::iterator - I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { - if (auto FE = FileMgr.getFile(*I)) + for (StringRef TopHeaderName : TopHeaderNames) + if (auto FE = FileMgr.getOptionalFileRef(TopHeaderName)) TopHeaders.insert(*FE); - } TopHeaderNames.clear(); } - return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); + return llvm::ArrayRef(TopHeaders.begin(), TopHeaders.end()); } -bool Module::directlyUses(const Module *Requested) const { +bool Module::directlyUses(const Module *Requested) { auto *Top = getTopLevelModule(); // A top-level module implicitly uses itself. @@ -280,10 +301,14 @@ bool Module::directlyUses(const Module *Requested) const { if (Requested->isSubModuleOf(Use)) return true; - // Anyone is allowed to use our builtin stddef.h and its accompanying module. - if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") + // Anyone is allowed to use our builtin stddef.h and its accompanying modules. + if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) || + Requested->fullModuleNameIs({"_Builtin_stddef_wint_t"})) return true; + if (NoUndeclaredIncludes) + UndeclaredUses.insert(Requested); + return false; } @@ -318,11 +343,9 @@ void Module::markUnavailable(bool Unimportable) { Current->IsAvailable = false; Current->IsUnimportable |= Unimportable; - for (submodule_iterator Sub = Current->submodule_begin(), - SubEnd = Current->submodule_end(); - Sub != SubEnd; ++Sub) { - if (needUpdate(*Sub)) - Stack.push_back(*Sub); + for (auto *Submodule : Current->submodules()) { + if (needUpdate(Submodule)) + Stack.push_back(Submodule); } } } @@ -350,6 +373,28 @@ Module *Module::findOrInferSubmodule(StringRef Name) { return Result; } +Module *Module::getGlobalModuleFragment() const { + assert(isNamedModuleUnit() && "We should only query the global module " + "fragment from the C++ 20 Named modules"); + + for (auto *SubModule : SubModules) + if (SubModule->isExplicitGlobalModule()) + return SubModule; + + return nullptr; +} + +Module *Module::getPrivateModuleFragment() const { + assert(isNamedModuleUnit() && "We should only query the private module " + "fragment from the C++ 20 Named modules"); + + for (auto *SubModule : SubModules) + if (SubModule->isPrivateModule()) + return SubModule; + + return nullptr; +} + void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { // All non-explicit submodules are exported. for (std::vector<Module *>::const_iterator I = SubModules.begin(), @@ -462,15 +507,15 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const { OS << "\n"; } - if (Header H = getUmbrellaHeader()) { + if (std::optional<Header> H = getUmbrellaHeaderAsWritten()) { OS.indent(Indent + 2); OS << "umbrella header \""; - OS.write_escaped(H.NameAsWritten); + OS.write_escaped(H->NameAsWritten); OS << "\"\n"; - } else if (DirectoryName D = getUmbrellaDir()) { + } else if (std::optional<DirectoryName> D = getUmbrellaDirAsWritten()) { OS.indent(Indent + 2); OS << "umbrella \""; - OS.write_escaped(D.NameAsWritten); + OS.write_escaped(D->NameAsWritten); OS << "\"\n"; } @@ -502,8 +547,8 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const { OS.indent(Indent + 2); OS << K.Prefix << "header \""; OS.write_escaped(H.NameAsWritten); - OS << "\" { size " << H.Entry->getSize() - << " mtime " << H.Entry->getModificationTime() << " }\n"; + OS << "\" { size " << H.Entry.getSize() + << " mtime " << H.Entry.getModificationTime() << " }\n"; } } for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) { @@ -529,14 +574,13 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const { OS << "export_as" << ExportAsModule << "\n"; } - for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); - MI != MIEnd; ++MI) + for (auto *Submodule : submodules()) // Print inferred subframework modules so that we don't need to re-infer // them (requires expensive directory iteration + stat calls) when we build // the module. Regular inferred submodules are OK, as we need to look at all // those header files anyway. - if (!(*MI)->IsInferred || (*MI)->IsFramework) - (*MI)->print(OS, Indent + 2, Dump); + if (!Submodule->IsInferred || Submodule->IsFramework) + Submodule->print(OS, Indent + 2, Dump); for (unsigned I = 0, N = Exports.size(); I != N; ++I) { OS.indent(Indent + 2); @@ -632,7 +676,9 @@ LLVM_DUMP_METHOD void Module::dump() const { void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, VisibleCallback Vis, ConflictCallback Cb) { - assert(Loc.isValid() && "setVisible expects a valid import location"); + // We can't import a global module fragment so the location can be invalid. + assert((M->isGlobalModule() || Loc.isValid()) && + "setVisible expects a valid import location"); if (isVisible(M)) return; @@ -652,7 +698,7 @@ void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, return; ImportLocs[ID] = Loc; - Vis(M); + Vis(V.M); // Make any exported modules visible. SmallVector<Module *, 16> Exports; @@ -675,6 +721,14 @@ void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, VisitModule({M, nullptr}); } +void VisibleModuleSet::makeTransitiveImportsVisible(Module *M, + SourceLocation Loc, + VisibleCallback Vis, + ConflictCallback Cb) { + for (auto *I : M->Imports) + setVisible(I, Loc, Vis, Cb); +} + ASTSourceDescriptor::ASTSourceDescriptor(Module &M) : Signature(M.Signature), ClangModule(&M) { if (M.Directory) diff --git a/contrib/llvm-project/clang/lib/Basic/NoSanitizeList.cpp b/contrib/llvm-project/clang/lib/Basic/NoSanitizeList.cpp index 3efd613b0d33..e7e63c1f419e 100644 --- a/contrib/llvm-project/clang/lib/Basic/NoSanitizeList.cpp +++ b/contrib/llvm-project/clang/lib/Basic/NoSanitizeList.cpp @@ -47,6 +47,11 @@ bool NoSanitizeList::containsFile(SanitizerMask Mask, StringRef FileName, return SSCL->inSection(Mask, "src", FileName, Category); } +bool NoSanitizeList::containsMainFile(SanitizerMask Mask, StringRef FileName, + StringRef Category) const { + return SSCL->inSection(Mask, "mainfile", FileName, Category); +} + bool NoSanitizeList::containsLocation(SanitizerMask Mask, SourceLocation Loc, StringRef Category) const { return Loc.isValid() && diff --git a/contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp b/contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp index b7408f39bdab..d39686ea688e 100644 --- a/contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp +++ b/contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp @@ -12,8 +12,21 @@ namespace clang { +// First feature in a pair requires the second one to be supported. +static const std::pair<StringRef, StringRef> DependentFeaturesList[] = { + {"__opencl_c_read_write_images", "__opencl_c_images"}, + {"__opencl_c_3d_image_writes", "__opencl_c_images"}, + {"__opencl_c_pipes", "__opencl_c_generic_address_space"}, + {"__opencl_c_device_enqueue", "__opencl_c_generic_address_space"}, + {"__opencl_c_device_enqueue", "__opencl_c_program_scope_global_variables"}}; + +// Extensions and equivalent feature pairs. +static const std::pair<StringRef, StringRef> FeatureExtensionMap[] = { + {"cl_khr_fp64", "__opencl_c_fp64"}, + {"cl_khr_3d_image_writes", "__opencl_c_3d_image_writes"}}; + bool OpenCLOptions::isKnown(llvm::StringRef Ext) const { - return OptMap.find(Ext) != OptMap.end(); + return OptMap.contains(Ext); } bool OpenCLOptions::isAvailableOption(llvm::StringRef Ext, @@ -108,42 +121,32 @@ void OpenCLOptions::disableAll() { bool OpenCLOptions::diagnoseUnsupportedFeatureDependencies( const TargetInfo &TI, DiagnosticsEngine &Diags) { - // Feature pairs. First feature in a pair requires the second one to be - // supported. - static const llvm::StringMap<llvm::StringRef> DependentFeaturesMap = { - {"__opencl_c_read_write_images", "__opencl_c_images"}, - {"__opencl_c_3d_image_writes", "__opencl_c_images"}, - {"__opencl_c_pipes", "__opencl_c_generic_address_space"}}; - auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts(); bool IsValid = true; - for (auto &FeaturePair : DependentFeaturesMap) - if (TI.hasFeatureEnabled(OpenCLFeaturesMap, FeaturePair.getKey()) && - !TI.hasFeatureEnabled(OpenCLFeaturesMap, FeaturePair.getValue())) { + for (auto &FeaturePair : DependentFeaturesList) { + auto Feature = FeaturePair.first; + auto Dep = FeaturePair.second; + if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Feature) && + !TI.hasFeatureEnabled(OpenCLFeaturesMap, Dep)) { IsValid = false; - Diags.Report(diag::err_opencl_feature_requires) - << FeaturePair.getKey() << FeaturePair.getValue(); + Diags.Report(diag::err_opencl_feature_requires) << Feature << Dep; } + } return IsValid; } bool OpenCLOptions::diagnoseFeatureExtensionDifferences( const TargetInfo &TI, DiagnosticsEngine &Diags) { - // Extensions and equivalent feature pairs. - static const llvm::StringMap<llvm::StringRef> FeatureExtensionMap = { - {"cl_khr_fp64", "__opencl_c_fp64"}, - {"cl_khr_3d_image_writes", "__opencl_c_3d_image_writes"}}; - auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts(); bool IsValid = true; for (auto &ExtAndFeat : FeatureExtensionMap) - if (TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.getKey()) != - TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.getValue())) { + if (TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.first) != + TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.second)) { IsValid = false; Diags.Report(diag::err_opencl_extension_and_feature_differs) - << ExtAndFeat.getKey() << ExtAndFeat.getValue(); + << ExtAndFeat.first << ExtAndFeat.second; } return IsValid; } diff --git a/contrib/llvm-project/clang/lib/Basic/OpenMPKinds.cpp b/contrib/llvm-project/clang/lib/Basic/OpenMPKinds.cpp index cfdba09eb1ec..6c31b0824eb8 100644 --- a/contrib/llvm-project/clang/lib/Basic/OpenMPKinds.cpp +++ b/contrib/llvm-project/clang/lib/Basic/OpenMPKinds.cpp @@ -21,7 +21,7 @@ using namespace clang; using namespace llvm::omp; unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, - unsigned OpenMPVersion) { + const LangOptions &LangOpts) { switch (Kind) { case OMPC_default: return llvm::StringSwitch<unsigned>(Str) @@ -41,11 +41,20 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, .Case(#Name, static_cast<unsigned>(OMPC_SCHEDULE_MODIFIER_##Name)) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_SCHEDULE_unknown); - case OMPC_depend: - return llvm::StringSwitch<OpenMPDependClauseKind>(Str) + case OMPC_depend: { + unsigned Type = llvm::StringSwitch<unsigned>(Str) #define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name) #include "clang/Basic/OpenMPKinds.def" - .Default(OMPC_DEPEND_unknown); + .Default(OMPC_DEPEND_unknown); + if (LangOpts.OpenMP < 51 && Type == OMPC_DEPEND_inoutset) + return OMPC_DEPEND_unknown; + return Type; + } + case OMPC_doacross: + return llvm::StringSwitch<OpenMPDoacrossClauseModifier>(Str) +#define OPENMP_DOACROSS_MODIFIER(Name) .Case(#Name, OMPC_DOACROSS_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_DOACROSS_unknown); case OMPC_linear: return llvm::StringSwitch<OpenMPLinearClauseKind>(Str) #define OPENMP_LINEAR_KIND(Name) .Case(#Name, OMPC_LINEAR_##Name) @@ -59,7 +68,9 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, .Case(#Name, static_cast<unsigned>(OMPC_MAP_MODIFIER_##Name)) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_MAP_unknown); - if (OpenMPVersion < 51 && Type == OMPC_MAP_MODIFIER_present) + if (LangOpts.OpenMP < 51 && Type == OMPC_MAP_MODIFIER_present) + return OMPC_MAP_MODIFIER_unknown; + if (!LangOpts.OpenMPExtensions && Type == OMPC_MAP_MODIFIER_ompx_hold) return OMPC_MAP_MODIFIER_unknown; return Type; } @@ -70,7 +81,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, .Case(#Name, static_cast<unsigned>(OMPC_MOTION_MODIFIER_##Name)) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_MOTION_MODIFIER_unknown); - if (OpenMPVersion < 51 && Type == OMPC_MOTION_MODIFIER_present) + if (LangOpts.OpenMP < 51 && Type == OMPC_MOTION_MODIFIER_present) return OMPC_MOTION_MODIFIER_unknown; return Type; } @@ -93,19 +104,37 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, .Case(#Name, OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown); + case OMPC_fail: + return static_cast<unsigned int>(llvm::StringSwitch<llvm::omp::Clause>(Str) +#define OPENMP_ATOMIC_FAIL_MODIFIER(Name) .Case(#Name, OMPC_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_unknown)); case OMPC_device_type: return llvm::StringSwitch<OpenMPDeviceType>(Str) #define OPENMP_DEVICE_TYPE_KIND(Name) .Case(#Name, OMPC_DEVICE_TYPE_##Name) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_DEVICE_TYPE_unknown); + case OMPC_at: + return llvm::StringSwitch<OpenMPAtClauseKind>(Str) +#define OPENMP_AT_KIND(Name) .Case(#Name, OMPC_AT_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_AT_unknown); + case OMPC_severity: + return llvm::StringSwitch<OpenMPSeverityClauseKind>(Str) +#define OPENMP_SEVERITY_KIND(Name) .Case(#Name, OMPC_SEVERITY_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_SEVERITY_unknown); case OMPC_lastprivate: return llvm::StringSwitch<OpenMPLastprivateModifier>(Str) #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) + return llvm::StringSwitch<unsigned>(Str) +#define OPENMP_ORDER_KIND(Name) \ + .Case(#Name, static_cast<unsigned>(OMPC_ORDER_##Name)) +#define OPENMP_ORDER_MODIFIER(Name) \ + .Case(#Name, static_cast<unsigned>(OMPC_ORDER_MODIFIER_##Name)) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_ORDER_unknown); case OMPC_update: @@ -123,6 +152,34 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, #define OPENMP_REDUCTION_MODIFIER(Name) .Case(#Name, OMPC_REDUCTION_##Name) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_REDUCTION_unknown); + case OMPC_adjust_args: + return llvm::StringSwitch<OpenMPAdjustArgsOpKind>(Str) +#define OPENMP_ADJUST_ARGS_KIND(Name) .Case(#Name, OMPC_ADJUST_ARGS_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_ADJUST_ARGS_unknown); + case OMPC_bind: + return llvm::StringSwitch<unsigned>(Str) +#define OPENMP_BIND_KIND(Name) .Case(#Name, OMPC_BIND_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_BIND_unknown); + case OMPC_grainsize: { + unsigned Type = llvm::StringSwitch<unsigned>(Str) +#define OPENMP_GRAINSIZE_MODIFIER(Name) .Case(#Name, OMPC_GRAINSIZE_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_GRAINSIZE_unknown); + if (LangOpts.OpenMP < 51) + return OMPC_GRAINSIZE_unknown; + return Type; + } + case OMPC_num_tasks: { + unsigned Type = llvm::StringSwitch<unsigned>(Str) +#define OPENMP_NUMTASKS_MODIFIER(Name) .Case(#Name, OMPC_NUMTASKS_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_NUMTASKS_unknown); + if (LangOpts.OpenMP < 51) + return OMPC_NUMTASKS_unknown; + return Type; + } case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -151,6 +208,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, case OMPC_read: case OMPC_write: case OMPC_capture: + case OMPC_compare: case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: @@ -161,14 +219,13 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, case OMPC_num_teams: case OMPC_thread_limit: case OMPC_priority: - case OMPC_grainsize: case OMPC_nogroup: - case OMPC_num_tasks: case OMPC_hint: case OMPC_uniform: case OMPC_use_device_ptr: case OMPC_use_device_addr: case OMPC_is_device_ptr: + case OMPC_has_device_addr: case OMPC_unified_address: case OMPC_unified_shared_memory: case OMPC_reverse_offload: @@ -183,6 +240,8 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, case OMPC_exclusive: case OMPC_uses_allocators: case OMPC_affinity: + case OMPC_when: + case OMPC_append_args: break; default: break; @@ -233,6 +292,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'depend' clause type"); + case OMPC_doacross: + switch (Type) { + case OMPC_DOACROSS_unknown: + return "unknown"; +#define OPENMP_DOACROSS_MODIFIER(Name) \ + case OMPC_DOACROSS_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'doacross' clause type"); case OMPC_linear: switch (Type) { case OMPC_LINEAR_unknown: @@ -316,6 +385,26 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'device_type' clause type"); + case OMPC_at: + switch (Type) { + case OMPC_AT_unknown: + return "unknown"; +#define OPENMP_AT_KIND(Name) \ + case OMPC_AT_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'at' clause type"); + case OMPC_severity: + switch (Type) { + case OMPC_SEVERITY_unknown: + return "unknown"; +#define OPENMP_SEVERITY_KIND(Name) \ + case OMPC_SEVERITY_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'severity' clause type"); case OMPC_lastprivate: switch (Type) { case OMPC_LASTPRIVATE_unknown: @@ -329,10 +418,14 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_order: switch (Type) { case OMPC_ORDER_unknown: + case OMPC_ORDER_MODIFIER_last: return "unknown"; #define OPENMP_ORDER_KIND(Name) \ - case OMPC_ORDER_##Name: \ - return #Name; + case OMPC_ORDER_##Name: \ + return #Name; +#define OPENMP_ORDER_MODIFIER(Name) \ + case OMPC_ORDER_MODIFIER_##Name: \ + return #Name; #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'order' clause type"); @@ -346,6 +439,11 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'depend' clause type"); + case OMPC_fail: { + OpenMPClauseKind CK = static_cast<OpenMPClauseKind>(Type); + return getOpenMPClauseName(CK).data(); + llvm_unreachable("Invalid OpenMP 'fail' clause modifier"); + } case OMPC_device: switch (Type) { case OMPC_DEVICE_unknown: @@ -366,6 +464,46 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'reduction' clause modifier"); + case OMPC_adjust_args: + switch (Type) { + case OMPC_ADJUST_ARGS_unknown: + return "unknown"; +#define OPENMP_ADJUST_ARGS_KIND(Name) \ + case OMPC_ADJUST_ARGS_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'adjust_args' clause kind"); + case OMPC_bind: + switch (Type) { + case OMPC_BIND_unknown: + return "unknown"; +#define OPENMP_BIND_KIND(Name) \ + case OMPC_BIND_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'bind' clause type"); + case OMPC_grainsize: + switch (Type) { + case OMPC_GRAINSIZE_unknown: + return "unknown"; +#define OPENMP_GRAINSIZE_MODIFIER(Name) \ + case OMPC_GRAINSIZE_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'grainsize' clause modifier"); + case OMPC_num_tasks: + switch (Type) { + case OMPC_NUMTASKS_unknown: + return "unknown"; +#define OPENMP_NUMTASKS_MODIFIER(Name) \ + case OMPC_NUMTASKS_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier"); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -394,6 +532,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_read: case OMPC_write: case OMPC_capture: + case OMPC_compare: case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: @@ -404,14 +543,13 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_num_teams: case OMPC_thread_limit: case OMPC_priority: - case OMPC_grainsize: case OMPC_nogroup: - case OMPC_num_tasks: case OMPC_hint: case OMPC_uniform: case OMPC_use_device_ptr: case OMPC_use_device_addr: case OMPC_is_device_ptr: + case OMPC_has_device_addr: case OMPC_unified_address: case OMPC_unified_shared_memory: case OMPC_reverse_offload: @@ -426,6 +564,8 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_exclusive: case OMPC_uses_allocators: case OMPC_affinity: + case OMPC_when: + case OMPC_append_args: break; default: break; @@ -440,7 +580,10 @@ bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_master_taskloop || DKind == OMPD_master_taskloop_simd || DKind == OMPD_parallel_master_taskloop || DKind == OMPD_parallel_master_taskloop_simd || - DKind == OMPD_distribute || DKind == OMPD_target_parallel_for || + DKind == OMPD_masked_taskloop || DKind == OMPD_masked_taskloop_simd || + DKind == OMPD_parallel_masked_taskloop || DKind == OMPD_distribute || + DKind == OMPD_parallel_masked_taskloop_simd || + DKind == OMPD_target_parallel_for || DKind == OMPD_distribute_parallel_for || DKind == OMPD_distribute_parallel_for_simd || DKind == OMPD_distribute_simd || @@ -453,7 +596,9 @@ bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_target_teams_distribute_parallel_for || DKind == OMPD_target_teams_distribute_parallel_for_simd || DKind == OMPD_target_teams_distribute_simd || DKind == OMPD_tile || - DKind == OMPD_unroll; + DKind == OMPD_unroll || DKind == OMPD_loop || + DKind == OMPD_teams_loop || DKind == OMPD_target_teams_loop || + DKind == OMPD_parallel_loop || DKind == OMPD_target_parallel_loop; } bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { @@ -468,13 +613,18 @@ bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_teams_distribute_parallel_for_simd || DKind == OMPD_teams_distribute_parallel_for || DKind == OMPD_target_teams_distribute_parallel_for || - DKind == OMPD_target_teams_distribute_parallel_for_simd; + DKind == OMPD_target_teams_distribute_parallel_for_simd || + DKind == OMPD_parallel_loop || DKind == OMPD_teams_loop || + DKind == OMPD_target_parallel_loop || DKind == OMPD_target_teams_loop; } bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_taskloop || DKind == OMPD_taskloop_simd || DKind == OMPD_master_taskloop || DKind == OMPD_master_taskloop_simd || DKind == OMPD_parallel_master_taskloop || + DKind == OMPD_masked_taskloop || DKind == OMPD_masked_taskloop_simd || + DKind == OMPD_parallel_masked_taskloop || + DKind == OMPD_parallel_masked_taskloop_simd || DKind == OMPD_parallel_master_taskloop_simd; } @@ -489,9 +639,13 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_teams_distribute_parallel_for_simd || DKind == OMPD_target_teams_distribute_parallel_for || DKind == OMPD_target_teams_distribute_parallel_for_simd || - DKind == OMPD_parallel_master || + DKind == OMPD_parallel_master || DKind == OMPD_parallel_masked || DKind == OMPD_parallel_master_taskloop || - DKind == OMPD_parallel_master_taskloop_simd; + DKind == OMPD_parallel_master_taskloop_simd || + DKind == OMPD_parallel_masked_taskloop || + DKind == OMPD_parallel_masked_taskloop_simd || + DKind == OMPD_parallel_loop || DKind == OMPD_target_parallel_loop || + DKind == OMPD_teams_loop; } bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) { @@ -501,7 +655,8 @@ bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute || DKind == OMPD_target_teams_distribute_parallel_for || DKind == OMPD_target_teams_distribute_parallel_for_simd || - DKind == OMPD_target_teams_distribute_simd; + DKind == OMPD_target_teams_distribute_simd || + DKind == OMPD_target_teams_loop || DKind == OMPD_target_parallel_loop; } bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) { @@ -513,22 +668,26 @@ bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_teams || DKind == OMPD_teams_distribute || DKind == OMPD_teams_distribute_simd || DKind == OMPD_teams_distribute_parallel_for_simd || - DKind == OMPD_teams_distribute_parallel_for; + DKind == OMPD_teams_distribute_parallel_for || + DKind == OMPD_teams_loop; } bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) { - return isOpenMPNestingTeamsDirective(DKind) || - DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute || + return isOpenMPNestingTeamsDirective(DKind) || DKind == OMPD_target_teams || + DKind == OMPD_target_teams_distribute || DKind == OMPD_target_teams_distribute_parallel_for || DKind == OMPD_target_teams_distribute_parallel_for_simd || - DKind == OMPD_target_teams_distribute_simd; + DKind == OMPD_target_teams_distribute_simd || + DKind == OMPD_target_teams_loop; } bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_simd || DKind == OMPD_for_simd || DKind == OMPD_parallel_for_simd || DKind == OMPD_taskloop_simd || DKind == OMPD_master_taskloop_simd || + DKind == OMPD_masked_taskloop_simd || DKind == OMPD_parallel_master_taskloop_simd || + DKind == OMPD_parallel_masked_taskloop_simd || DKind == OMPD_distribute_parallel_for_simd || DKind == OMPD_distribute_simd || DKind == OMPD_target_simd || DKind == OMPD_teams_distribute_simd || @@ -556,6 +715,12 @@ bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) { Kind == OMPD_target_teams_distribute_simd; } +bool clang::isOpenMPGenericLoopDirective(OpenMPDirectiveKind Kind) { + return Kind == OMPD_loop || Kind == OMPD_teams_loop || + Kind == OMPD_target_teams_loop || Kind == OMPD_parallel_loop || + Kind == OMPD_target_parallel_loop; +} + bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) { return Kind == OMPC_private || Kind == OMPC_firstprivate || Kind == OMPC_lastprivate || Kind == OMPC_linear || @@ -577,25 +742,46 @@ bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) { Kind == OMPD_teams_distribute_parallel_for_simd || Kind == OMPD_teams_distribute_parallel_for || Kind == OMPD_target_teams_distribute_parallel_for || - Kind == OMPD_target_teams_distribute_parallel_for_simd; + Kind == OMPD_target_teams_distribute_parallel_for_simd || + Kind == OMPD_teams_loop || Kind == OMPD_target_teams_loop; } bool clang::isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_tile || DKind == OMPD_unroll; } +bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind) { + return DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd || + DKind == OMPD_parallel_master || + DKind == OMPD_parallel_master_taskloop || + DKind == OMPD_parallel_master_taskloop_simd || + DKind == OMPD_parallel_sections; +} + +bool clang::needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind) { + return DKind == OMPD_target || DKind == OMPD_target_parallel || + DKind == OMPD_target_parallel_for || + DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd || + DKind == OMPD_target_parallel_loop; +} + void clang::getOpenMPCaptureRegions( SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions, OpenMPDirectiveKind DKind) { assert(unsigned(DKind) < llvm::omp::Directive_enumSize); switch (DKind) { + case OMPD_metadirective: + CaptureRegions.push_back(OMPD_metadirective); + break; case OMPD_parallel: case OMPD_parallel_for: case OMPD_parallel_for_simd: case OMPD_parallel_master: + case OMPD_parallel_masked: case OMPD_parallel_sections: case OMPD_distribute_parallel_for: case OMPD_distribute_parallel_for_simd: + case OMPD_parallel_loop: CaptureRegions.push_back(OMPD_parallel); break; case OMPD_target_teams: @@ -615,6 +801,7 @@ void clang::getOpenMPCaptureRegions( CaptureRegions.push_back(OMPD_task); CaptureRegions.push_back(OMPD_target); break; + case OMPD_teams_loop: case OMPD_teams_distribute_parallel_for: case OMPD_teams_distribute_parallel_for_simd: CaptureRegions.push_back(OMPD_teams); @@ -623,6 +810,7 @@ void clang::getOpenMPCaptureRegions( case OMPD_target_parallel: case OMPD_target_parallel_for: case OMPD_target_parallel_for_simd: + case OMPD_target_parallel_loop: CaptureRegions.push_back(OMPD_task); CaptureRegions.push_back(OMPD_target); CaptureRegions.push_back(OMPD_parallel); @@ -637,13 +825,18 @@ void clang::getOpenMPCaptureRegions( case OMPD_taskloop_simd: case OMPD_master_taskloop: case OMPD_master_taskloop_simd: + case OMPD_masked_taskloop: + case OMPD_masked_taskloop_simd: CaptureRegions.push_back(OMPD_taskloop); break; + case OMPD_parallel_masked_taskloop: + case OMPD_parallel_masked_taskloop_simd: case OMPD_parallel_master_taskloop: case OMPD_parallel_master_taskloop_simd: CaptureRegions.push_back(OMPD_parallel); CaptureRegions.push_back(OMPD_taskloop); break; + case OMPD_target_teams_loop: case OMPD_target_teams_distribute_parallel_for: case OMPD_target_teams_distribute_parallel_for_simd: CaptureRegions.push_back(OMPD_task); @@ -651,6 +844,13 @@ void clang::getOpenMPCaptureRegions( CaptureRegions.push_back(OMPD_teams); CaptureRegions.push_back(OMPD_parallel); break; + case OMPD_nothing: + CaptureRegions.push_back(OMPD_nothing); + break; + case OMPD_loop: + // TODO: 'loop' may require different capture regions depending on the bind + // clause or the parent directive when there is no bind clause. Use + // OMPD_unknown for now. case OMPD_simd: case OMPD_for: case OMPD_for_simd: @@ -665,6 +865,7 @@ void clang::getOpenMPCaptureRegions( case OMPD_atomic: case OMPD_target_data: case OMPD_distribute_simd: + case OMPD_scope: case OMPD_dispatch: CaptureRegions.push_back(OMPD_unknown); break; @@ -676,6 +877,7 @@ void clang::getOpenMPCaptureRegions( case OMPD_allocate: case OMPD_taskyield: case OMPD_barrier: + case OMPD_error: case OMPD_taskwait: case OMPD_cancellation_point: case OMPD_cancel: @@ -697,3 +899,10 @@ void clang::getOpenMPCaptureRegions( llvm_unreachable("Unknown OpenMP directive"); } } + +bool clang::checkFailClauseParameter(OpenMPClauseKind FailClauseParameter) { + return FailClauseParameter == llvm::omp::OMPC_acquire || + FailClauseParameter == llvm::omp::OMPC_relaxed || + FailClauseParameter == llvm::omp::OMPC_seq_cst; +} + diff --git a/contrib/llvm-project/clang/lib/Basic/ParsedAttrInfo.cpp b/contrib/llvm-project/clang/lib/Basic/ParsedAttrInfo.cpp new file mode 100644 index 000000000000..16fa314b642b --- /dev/null +++ b/contrib/llvm-project/clang/lib/Basic/ParsedAttrInfo.cpp @@ -0,0 +1,32 @@ +//===- ParsedAttrInfo.cpp - Registry for attribute plugins ------*- 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 contains the Registry of attributes added by plugins which +// derive the ParsedAttrInfo class. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/ParsedAttrInfo.h" +#include "llvm/Support/ManagedStatic.h" +#include <list> +#include <memory> + +using namespace clang; + +LLVM_INSTANTIATE_REGISTRY(ParsedAttrInfoRegistry) + +const std::list<std::unique_ptr<ParsedAttrInfo>> & +clang::getAttributePluginInstances() { + static llvm::ManagedStatic<std::list<std::unique_ptr<ParsedAttrInfo>>> + PluginAttrInstances; + if (PluginAttrInstances->empty()) + for (const auto &It : ParsedAttrInfoRegistry::entries()) + PluginAttrInstances->emplace_back(It.instantiate()); + + return *PluginAttrInstances; +} diff --git a/contrib/llvm-project/clang/lib/Basic/ProfileList.cpp b/contrib/llvm-project/clang/lib/Basic/ProfileList.cpp index 2cb05c1c3c07..8fa16e2eb069 100644 --- a/contrib/llvm-project/clang/lib/Basic/ProfileList.cpp +++ b/contrib/llvm-project/clang/lib/Basic/ProfileList.cpp @@ -17,6 +17,7 @@ #include "llvm/Support/SpecialCaseList.h" #include "llvm/Support/raw_ostream.h" +#include <optional> using namespace clang; @@ -35,8 +36,8 @@ public: bool isEmpty() const { return Sections.empty(); } bool hasPrefix(StringRef Prefix) const { - for (auto &SectionIter : Sections) - if (SectionIter.Entries.count(Prefix) > 0) + for (const auto &It : Sections) + if (It.second.Entries.count(Prefix) > 0) return true; return false; } @@ -58,7 +59,7 @@ ProfileSpecialCaseList::createOrDie(const std::vector<std::string> &Paths, std::string Error; if (auto PSCL = create(Paths, VFS, Error)) return PSCL; - llvm::report_fatal_error(Error); + llvm::report_fatal_error(llvm::Twine(Error)); } } @@ -66,8 +67,7 @@ ProfileSpecialCaseList::createOrDie(const std::vector<std::string> &Paths, ProfileList::ProfileList(ArrayRef<std::string> Paths, SourceManager &SM) : SCL(ProfileSpecialCaseList::createOrDie( Paths, SM.getFileManager().getVirtualFileSystem())), - Empty(SCL->isEmpty()), - Default(SCL->hasPrefix("fun") || SCL->hasPrefix("src")), SM(SM) {} + Empty(SCL->isEmpty()), SM(SM) {} ProfileList::~ProfileList() = default; @@ -85,30 +85,66 @@ static StringRef getSectionName(CodeGenOptions::ProfileInstrKind Kind) { llvm_unreachable("Unhandled CodeGenOptions::ProfileInstrKind enum"); } -llvm::Optional<bool> +ProfileList::ExclusionType +ProfileList::getDefault(CodeGenOptions::ProfileInstrKind Kind) const { + StringRef Section = getSectionName(Kind); + // Check for "default:<type>" + if (SCL->inSection(Section, "default", "allow")) + return Allow; + if (SCL->inSection(Section, "default", "skip")) + return Skip; + if (SCL->inSection(Section, "default", "forbid")) + return Forbid; + // If any cases use "fun" or "src", set the default to FORBID. + if (SCL->hasPrefix("fun") || SCL->hasPrefix("src")) + return Forbid; + return Allow; +} + +std::optional<ProfileList::ExclusionType> +ProfileList::inSection(StringRef Section, StringRef Prefix, + StringRef Query) const { + if (SCL->inSection(Section, Prefix, Query, "allow")) + return Allow; + if (SCL->inSection(Section, Prefix, Query, "skip")) + return Skip; + if (SCL->inSection(Section, Prefix, Query, "forbid")) + return Forbid; + if (SCL->inSection(Section, Prefix, Query)) + return Allow; + return std::nullopt; +} + +std::optional<ProfileList::ExclusionType> ProfileList::isFunctionExcluded(StringRef FunctionName, CodeGenOptions::ProfileInstrKind Kind) const { StringRef Section = getSectionName(Kind); + // Check for "function:<regex>=<case>" + if (auto V = inSection(Section, "function", FunctionName)) + return V; if (SCL->inSection(Section, "!fun", FunctionName)) - return true; + return Forbid; if (SCL->inSection(Section, "fun", FunctionName)) - return false; - return None; + return Allow; + return std::nullopt; } -llvm::Optional<bool> +std::optional<ProfileList::ExclusionType> ProfileList::isLocationExcluded(SourceLocation Loc, CodeGenOptions::ProfileInstrKind Kind) const { return isFileExcluded(SM.getFilename(SM.getFileLoc(Loc)), Kind); } -llvm::Optional<bool> +std::optional<ProfileList::ExclusionType> ProfileList::isFileExcluded(StringRef FileName, CodeGenOptions::ProfileInstrKind Kind) const { StringRef Section = getSectionName(Kind); + // Check for "source:<regex>=<case>" + if (auto V = inSection(Section, "source", FileName)) + return V; if (SCL->inSection(Section, "!src", FileName)) - return true; + return Forbid; if (SCL->inSection(Section, "src", FileName)) - return false; - return None; + return Allow; + return std::nullopt; } diff --git a/contrib/llvm-project/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/contrib/llvm-project/clang/lib/Basic/SanitizerSpecialCaseList.cpp index 5bf8d39ffd95..b02e868cdaa4 100644 --- a/contrib/llvm-project/clang/lib/Basic/SanitizerSpecialCaseList.cpp +++ b/contrib/llvm-project/clang/lib/Basic/SanitizerSpecialCaseList.cpp @@ -33,11 +33,12 @@ SanitizerSpecialCaseList::createOrDie(const std::vector<std::string> &Paths, std::string Error; if (auto SSCL = create(Paths, VFS, Error)) return SSCL; - llvm::report_fatal_error(Error); + llvm::report_fatal_error(StringRef(Error)); } void SanitizerSpecialCaseList::createSanitizerSections() { - for (auto &S : Sections) { + for (auto &It : Sections) { + auto &S = It.second; SanitizerMask Mask; #define SANITIZER(NAME, ID) \ diff --git a/contrib/llvm-project/clang/lib/Basic/Sanitizers.cpp b/contrib/llvm-project/clang/lib/Basic/Sanitizers.cpp index 7d903c8fdf5e..62ccdf8e9bbf 100644 --- a/contrib/llvm-project/clang/lib/Basic/Sanitizers.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Sanitizers.cpp @@ -61,7 +61,7 @@ namespace clang { unsigned SanitizerMask::countPopulation() const { unsigned total = 0; for (const auto &Val : maskLoToHigh) - total += llvm::countPopulation(Val); + total += llvm::popcount(Val); return total; } diff --git a/contrib/llvm-project/clang/lib/Basic/Sarif.cpp b/contrib/llvm-project/clang/lib/Basic/Sarif.cpp new file mode 100644 index 000000000000..1cae7b937bc6 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Basic/Sarif.cpp @@ -0,0 +1,425 @@ +//===-- clang/Basic/Sarif.cpp - SarifDocumentWriter class definition ------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains the declaration of the SARIFDocumentWriter class, and +/// associated builders such as: +/// - \ref SarifArtifact +/// - \ref SarifArtifactLocation +/// - \ref SarifRule +/// - \ref SarifResult +//===----------------------------------------------------------------------===// +#include "clang/Basic/Sarif.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/JSON.h" +#include "llvm/Support/Path.h" + +#include <optional> +#include <string> +#include <utility> + +using namespace clang; +using namespace llvm; + +using clang::detail::SarifArtifact; +using clang::detail::SarifArtifactLocation; + +static StringRef getFileName(FileEntryRef FE) { + StringRef Filename = FE.getFileEntry().tryGetRealPathName(); + if (Filename.empty()) + Filename = FE.getName(); + return Filename; +} +/// \name URI +/// @{ + +/// \internal +/// \brief +/// Return the RFC3986 encoding of the input character. +/// +/// \param C Character to encode to RFC3986. +/// +/// \return The RFC3986 representation of \c C. +static std::string percentEncodeURICharacter(char C) { + // RFC 3986 claims alpha, numeric, and this handful of + // characters are not reserved for the path component and + // should be written out directly. Otherwise, percent + // encode the character and write that out instead of the + // reserved character. + if (llvm::isAlnum(C) || + StringRef::npos != StringRef("-._~:@!$&'()*+,;=").find(C)) + return std::string(&C, 1); + return "%" + llvm::toHex(StringRef(&C, 1)); +} + +/// \internal +/// \brief Return a URI representing the given file name. +/// +/// \param Filename The filename to be represented as URI. +/// +/// \return RFC3986 URI representing the input file name. +static std::string fileNameToURI(StringRef Filename) { + SmallString<32> Ret = StringRef("file://"); + + // Get the root name to see if it has a URI authority. + StringRef Root = sys::path::root_name(Filename); + if (Root.starts_with("//")) { + // There is an authority, so add it to the URI. + Ret += Root.drop_front(2).str(); + } else if (!Root.empty()) { + // There is no authority, so end the component and add the root to the URI. + Ret += Twine("/" + Root).str(); + } + + auto Iter = sys::path::begin(Filename), End = sys::path::end(Filename); + assert(Iter != End && "Expected there to be a non-root path component."); + // Add the rest of the path components, encoding any reserved characters; + // we skip past the first path component, as it was handled it above. + for (StringRef Component : llvm::make_range(++Iter, End)) { + // For reasons unknown to me, we may get a backslash with Windows native + // paths for the initial backslash following the drive component, which + // we need to ignore as a URI path part. + if (Component == "\\") + continue; + + // Add the separator between the previous path part and the one being + // currently processed. + Ret += "/"; + + // URI encode the part. + for (char C : Component) { + Ret += percentEncodeURICharacter(C); + } + } + + return std::string(Ret); +} +/// @} + +/// \brief Calculate the column position expressed in the number of UTF-8 code +/// points from column start to the source location +/// +/// \param Loc The source location whose column needs to be calculated. +/// \param TokenLen Optional hint for when the token is multiple bytes long. +/// +/// \return The column number as a UTF-8 aware byte offset from column start to +/// the effective source location. +static unsigned int adjustColumnPos(FullSourceLoc Loc, + unsigned int TokenLen = 0) { + assert(!Loc.isInvalid() && "invalid Loc when adjusting column position"); + + std::pair<FileID, unsigned> LocInfo = Loc.getDecomposedExpansionLoc(); + std::optional<MemoryBufferRef> Buf = + Loc.getManager().getBufferOrNone(LocInfo.first); + assert(Buf && "got an invalid buffer for the location's file"); + assert(Buf->getBufferSize() >= (LocInfo.second + TokenLen) && + "token extends past end of buffer?"); + + // Adjust the offset to be the start of the line, since we'll be counting + // Unicode characters from there until our column offset. + unsigned int Off = LocInfo.second - (Loc.getExpansionColumnNumber() - 1); + unsigned int Ret = 1; + while (Off < (LocInfo.second + TokenLen)) { + Off += getNumBytesForUTF8(Buf->getBuffer()[Off]); + Ret++; + } + + return Ret; +} + +/// \name SARIF Utilities +/// @{ + +/// \internal +json::Object createMessage(StringRef Text) { + return json::Object{{"text", Text.str()}}; +} + +/// \internal +/// \pre CharSourceRange must be a token range +static json::Object createTextRegion(const SourceManager &SM, + const CharSourceRange &R) { + FullSourceLoc BeginCharLoc{R.getBegin(), SM}; + FullSourceLoc EndCharLoc{R.getEnd(), SM}; + json::Object Region{{"startLine", BeginCharLoc.getExpansionLineNumber()}, + {"startColumn", adjustColumnPos(BeginCharLoc)}}; + + if (BeginCharLoc == EndCharLoc) { + Region["endColumn"] = adjustColumnPos(BeginCharLoc); + } else { + Region["endLine"] = EndCharLoc.getExpansionLineNumber(); + Region["endColumn"] = adjustColumnPos(EndCharLoc); + } + return Region; +} + +static json::Object createLocation(json::Object &&PhysicalLocation, + StringRef Message = "") { + json::Object Ret{{"physicalLocation", std::move(PhysicalLocation)}}; + if (!Message.empty()) + Ret.insert({"message", createMessage(Message)}); + return Ret; +} + +static StringRef importanceToStr(ThreadFlowImportance I) { + switch (I) { + case ThreadFlowImportance::Important: + return "important"; + case ThreadFlowImportance::Essential: + return "essential"; + case ThreadFlowImportance::Unimportant: + return "unimportant"; + } + llvm_unreachable("Fully covered switch is not so fully covered"); +} + +static StringRef resultLevelToStr(SarifResultLevel R) { + switch (R) { + case SarifResultLevel::None: + return "none"; + case SarifResultLevel::Note: + return "note"; + case SarifResultLevel::Warning: + return "warning"; + case SarifResultLevel::Error: + return "error"; + } + llvm_unreachable("Potentially un-handled SarifResultLevel. " + "Is the switch not fully covered?"); +} + +static json::Object +createThreadFlowLocation(json::Object &&Location, + const ThreadFlowImportance &Importance) { + return json::Object{{"location", std::move(Location)}, + {"importance", importanceToStr(Importance)}}; +} +/// @} + +json::Object +SarifDocumentWriter::createPhysicalLocation(const CharSourceRange &R) { + assert(R.isValid() && + "Cannot create a physicalLocation from invalid SourceRange!"); + assert(R.isCharRange() && + "Cannot create a physicalLocation from a token range!"); + FullSourceLoc Start{R.getBegin(), SourceMgr}; + OptionalFileEntryRef FE = Start.getExpansionLoc().getFileEntryRef(); + assert(FE && "Diagnostic does not exist within a valid file!"); + + const std::string &FileURI = fileNameToURI(getFileName(*FE)); + auto I = CurrentArtifacts.find(FileURI); + + if (I == CurrentArtifacts.end()) { + uint32_t Idx = static_cast<uint32_t>(CurrentArtifacts.size()); + const SarifArtifactLocation &Location = + SarifArtifactLocation::create(FileURI).setIndex(Idx); + const SarifArtifact &Artifact = SarifArtifact::create(Location) + .setRoles({"resultFile"}) + .setLength(FE->getSize()) + .setMimeType("text/plain"); + auto StatusIter = CurrentArtifacts.insert({FileURI, Artifact}); + // If inserted, ensure the original iterator points to the newly inserted + // element, so it can be used downstream. + if (StatusIter.second) + I = StatusIter.first; + } + assert(I != CurrentArtifacts.end() && "Failed to insert new artifact"); + const SarifArtifactLocation &Location = I->second.Location; + json::Object ArtifactLocationObject{{"uri", Location.URI}}; + if (Location.Index.has_value()) + ArtifactLocationObject["index"] = *Location.Index; + return json::Object{{{"artifactLocation", std::move(ArtifactLocationObject)}, + {"region", createTextRegion(SourceMgr, R)}}}; +} + +json::Object &SarifDocumentWriter::getCurrentTool() { + assert(!Closed && "SARIF Document is closed. " + "Need to call createRun() before using getcurrentTool!"); + + // Since Closed = false here, expect there to be at least 1 Run, anything + // else is an invalid state. + assert(!Runs.empty() && "There are no runs associated with the document!"); + + return *Runs.back().getAsObject()->get("tool")->getAsObject(); +} + +void SarifDocumentWriter::reset() { + CurrentRules.clear(); + CurrentArtifacts.clear(); +} + +void SarifDocumentWriter::endRun() { + // Exit early if trying to close a closed Document. + if (Closed) { + reset(); + return; + } + + // Since Closed = false here, expect there to be at least 1 Run, anything + // else is an invalid state. + assert(!Runs.empty() && "There are no runs associated with the document!"); + + // Flush all the rules. + json::Object &Tool = getCurrentTool(); + json::Array Rules; + for (const SarifRule &R : CurrentRules) { + json::Object Config{ + {"enabled", R.DefaultConfiguration.Enabled}, + {"level", resultLevelToStr(R.DefaultConfiguration.Level)}, + {"rank", R.DefaultConfiguration.Rank}}; + json::Object Rule{ + {"name", R.Name}, + {"id", R.Id}, + {"fullDescription", json::Object{{"text", R.Description}}}, + {"defaultConfiguration", std::move(Config)}}; + if (!R.HelpURI.empty()) + Rule["helpUri"] = R.HelpURI; + Rules.emplace_back(std::move(Rule)); + } + json::Object &Driver = *Tool.getObject("driver"); + Driver["rules"] = std::move(Rules); + + // Flush all the artifacts. + json::Object &Run = getCurrentRun(); + json::Array *Artifacts = Run.getArray("artifacts"); + SmallVector<std::pair<StringRef, SarifArtifact>, 0> Vec; + for (const auto &[K, V] : CurrentArtifacts) + Vec.emplace_back(K, V); + llvm::sort(Vec, llvm::less_first()); + for (const auto &[_, A] : Vec) { + json::Object Loc{{"uri", A.Location.URI}}; + if (A.Location.Index.has_value()) { + Loc["index"] = static_cast<int64_t>(*A.Location.Index); + } + json::Object Artifact; + Artifact["location"] = std::move(Loc); + if (A.Length.has_value()) + Artifact["length"] = static_cast<int64_t>(*A.Length); + if (!A.Roles.empty()) + Artifact["roles"] = json::Array(A.Roles); + if (!A.MimeType.empty()) + Artifact["mimeType"] = A.MimeType; + if (A.Offset.has_value()) + Artifact["offset"] = *A.Offset; + Artifacts->push_back(json::Value(std::move(Artifact))); + } + + // Clear, reset temporaries before next run. + reset(); + + // Mark the document as closed. + Closed = true; +} + +json::Array +SarifDocumentWriter::createThreadFlows(ArrayRef<ThreadFlow> ThreadFlows) { + json::Object Ret{{"locations", json::Array{}}}; + json::Array Locs; + for (const auto &ThreadFlow : ThreadFlows) { + json::Object PLoc = createPhysicalLocation(ThreadFlow.Range); + json::Object Loc = createLocation(std::move(PLoc), ThreadFlow.Message); + Locs.emplace_back( + createThreadFlowLocation(std::move(Loc), ThreadFlow.Importance)); + } + Ret["locations"] = std::move(Locs); + return json::Array{std::move(Ret)}; +} + +json::Object +SarifDocumentWriter::createCodeFlow(ArrayRef<ThreadFlow> ThreadFlows) { + return json::Object{{"threadFlows", createThreadFlows(ThreadFlows)}}; +} + +void SarifDocumentWriter::createRun(StringRef ShortToolName, + StringRef LongToolName, + StringRef ToolVersion) { + // Clear resources associated with a previous run. + endRun(); + + // Signify a new run has begun. + Closed = false; + + json::Object Tool{ + {"driver", + json::Object{{"name", ShortToolName}, + {"fullName", LongToolName}, + {"language", "en-US"}, + {"version", ToolVersion}, + {"informationUri", + "https://clang.llvm.org/docs/UsersManual.html"}}}}; + json::Object TheRun{{"tool", std::move(Tool)}, + {"results", {}}, + {"artifacts", {}}, + {"columnKind", "unicodeCodePoints"}}; + Runs.emplace_back(std::move(TheRun)); +} + +json::Object &SarifDocumentWriter::getCurrentRun() { + assert(!Closed && + "SARIF Document is closed. " + "Can only getCurrentRun() if document is opened via createRun(), " + "create a run first"); + + // Since Closed = false here, expect there to be at least 1 Run, anything + // else is an invalid state. + assert(!Runs.empty() && "There are no runs associated with the document!"); + return *Runs.back().getAsObject(); +} + +size_t SarifDocumentWriter::createRule(const SarifRule &Rule) { + size_t Ret = CurrentRules.size(); + CurrentRules.emplace_back(Rule); + return Ret; +} + +void SarifDocumentWriter::appendResult(const SarifResult &Result) { + size_t RuleIdx = Result.RuleIdx; + assert(RuleIdx < CurrentRules.size() && + "Trying to reference a rule that doesn't exist"); + const SarifRule &Rule = CurrentRules[RuleIdx]; + assert(Rule.DefaultConfiguration.Enabled && + "Cannot add a result referencing a disabled Rule"); + json::Object Ret{{"message", createMessage(Result.DiagnosticMessage)}, + {"ruleIndex", static_cast<int64_t>(RuleIdx)}, + {"ruleId", Rule.Id}}; + if (!Result.Locations.empty()) { + json::Array Locs; + for (auto &Range : Result.Locations) { + Locs.emplace_back(createLocation(createPhysicalLocation(Range))); + } + Ret["locations"] = std::move(Locs); + } + if (!Result.ThreadFlows.empty()) + Ret["codeFlows"] = json::Array{createCodeFlow(Result.ThreadFlows)}; + + Ret["level"] = resultLevelToStr( + Result.LevelOverride.value_or(Rule.DefaultConfiguration.Level)); + + json::Object &Run = getCurrentRun(); + json::Array *Results = Run.getArray("results"); + Results->emplace_back(std::move(Ret)); +} + +json::Object SarifDocumentWriter::createDocument() { + // Flush all temporaries to their destinations if needed. + endRun(); + + json::Object Doc{ + {"$schema", SchemaURI}, + {"version", SchemaVersion}, + }; + if (!Runs.empty()) + Doc["runs"] = json::Array(Runs); + return Doc; +} diff --git a/contrib/llvm-project/clang/lib/Basic/SourceLocation.cpp b/contrib/llvm-project/clang/lib/Basic/SourceLocation.cpp index 6986fcd322f2..37baf643a0a9 100644 --- a/contrib/llvm-project/clang/lib/Basic/SourceLocation.cpp +++ b/contrib/llvm-project/clang/lib/Basic/SourceLocation.cpp @@ -42,11 +42,11 @@ void PrettyStackTraceLoc::print(raw_ostream &OS) const { // SourceLocation //===----------------------------------------------------------------------===// -static_assert(std::is_trivially_destructible<SourceLocation>::value, +static_assert(std::is_trivially_destructible_v<SourceLocation>, "SourceLocation must be trivially destructible because it is " "used in unions"); -static_assert(std::is_trivially_destructible<SourceRange>::value, +static_assert(std::is_trivially_destructible_v<SourceRange>, "SourceRange must be trivially destructible because it is " "used in unions"); @@ -90,7 +90,7 @@ SourceLocation::printToString(const SourceManager &SM) const { std::string S; llvm::raw_string_ostream OS(S); print(OS, SM); - return OS.str(); + return S; } LLVM_DUMP_METHOD void SourceLocation::dump(const SourceManager &SM) const { @@ -149,7 +149,7 @@ SourceRange::printToString(const SourceManager &SM) const { std::string S; llvm::raw_string_ostream OS(S); print(OS, SM); - return OS.str(); + return S; } //===----------------------------------------------------------------------===// @@ -166,6 +166,10 @@ FullSourceLoc FullSourceLoc::getExpansionLoc() const { return FullSourceLoc(SrcMgr->getExpansionLoc(*this), *SrcMgr); } +std::pair<FileID, unsigned> FullSourceLoc::getDecomposedExpansionLoc() const { + return SrcMgr->getDecomposedExpansionLoc(*this); +} + FullSourceLoc FullSourceLoc::getSpellingLoc() const { assert(isValid()); return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr); @@ -223,6 +227,11 @@ const FileEntry *FullSourceLoc::getFileEntry() const { return SrcMgr->getFileEntryForID(getFileID()); } +OptionalFileEntryRef FullSourceLoc::getFileEntryRef() const { + assert(isValid()); + return SrcMgr->getFileEntryRefForID(getFileID()); +} + unsigned FullSourceLoc::getExpansionLineNumber(bool *Invalid) const { assert(isValid()); return SrcMgr->getExpansionLineNumber(*this, Invalid); diff --git a/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp b/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp index 8cba379aa0f8..37734d3b10e7 100644 --- a/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp +++ b/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp @@ -17,8 +17,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManagerInternals.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -38,6 +37,7 @@ #include <cstddef> #include <cstdint> #include <memory> +#include <optional> #include <tuple> #include <utility> #include <vector> @@ -59,12 +59,10 @@ unsigned ContentCache::getSizeBytesMapped() const { /// Returns the kind of memory used to back the memory buffer for /// this content cache. This is used for performance analysis. llvm::MemoryBuffer::BufferKind ContentCache::getMemoryBufferKind() const { - assert(Buffer); - - // Should be unreachable, but keep for sanity. - if (!Buffer) + if (Buffer == nullptr) { + assert(0 && "Buffer should never be null"); return llvm::MemoryBuffer::MemoryBuffer_Malloc; - + } return Buffer->getBufferKind(); } @@ -100,23 +98,23 @@ const char *ContentCache::getInvalidBOM(StringRef BufStr) { return InvalidBOM; } -llvm::Optional<llvm::MemoryBufferRef> +std::optional<llvm::MemoryBufferRef> ContentCache::getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM, SourceLocation Loc) const { // Lazily create the Buffer for ContentCaches that wrap files. If we already // computed it, just return what we have. if (IsBufferInvalid) - return None; + return std::nullopt; if (Buffer) return Buffer->getMemBufferRef(); if (!ContentsEntry) - return None; + return std::nullopt; // Start with the assumption that the buffer is invalid to simplify early // return paths. IsBufferInvalid = true; - auto BufferOrError = FM.getBufferForFile(ContentsEntry, IsFileVolatile); + auto BufferOrError = FM.getBufferForFile(*ContentsEntry, IsFileVolatile); // If we were unable to open the file, then we are in an inconsistent // situation where the content cache referenced a file which no longer @@ -132,7 +130,7 @@ ContentCache::getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM, Diag.Report(Loc, diag::err_cannot_open_file) << ContentsEntry->getName() << BufferOrError.getError().message(); - return None; + return std::nullopt; } Buffer = std::move(*BufferOrError); @@ -154,7 +152,7 @@ ContentCache::getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM, Diag.Report(Loc, diag::err_file_too_large) << ContentsEntry->getName(); - return None; + return std::nullopt; } // Unless this is a named pipe (in which case we can handle a mismatch), @@ -169,7 +167,7 @@ ContentCache::getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM, Diag.Report(Loc, diag::err_file_modified) << ContentsEntry->getName(); - return None; + return std::nullopt; } // If the buffer is valid, check to see if it has a UTF Byte Order Mark @@ -181,7 +179,7 @@ ContentCache::getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM, if (InvalidBOM) { Diag.Report(Loc, diag::err_unsupported_bom) << InvalidBOM << ContentsEntry->getName(); - return None; + return std::nullopt; } // Buffer has been validated. @@ -207,28 +205,30 @@ void LineTableInfo::AddLineNote(FileID FID, unsigned Offset, unsigned LineNo, SrcMgr::CharacteristicKind FileKind) { std::vector<LineEntry> &Entries = LineEntries[FID]; - // An unspecified FilenameID means use the last filename if available, or the - // main source file otherwise. - if (FilenameID == -1 && !Entries.empty()) - FilenameID = Entries.back().FilenameID; - assert((Entries.empty() || Entries.back().FileOffset < Offset) && "Adding line entries out of order!"); unsigned IncludeOffset = 0; - if (EntryExit == 0) { // No #include stack change. - IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset; - } else if (EntryExit == 1) { + if (EntryExit == 1) { + // Push #include IncludeOffset = Offset-1; - } else if (EntryExit == 2) { - assert(!Entries.empty() && Entries.back().IncludeOffset && - "PPDirectives should have caught case when popping empty include stack"); - - // Get the include loc of the last entries' include loc as our include loc. - IncludeOffset = 0; - if (const LineEntry *PrevEntry = - FindNearestLineEntry(FID, Entries.back().IncludeOffset)) + } else { + const auto *PrevEntry = Entries.empty() ? nullptr : &Entries.back(); + if (EntryExit == 2) { + // Pop #include + assert(PrevEntry && PrevEntry->IncludeOffset && + "PPDirectives should have caught case when popping empty include " + "stack"); + PrevEntry = FindNearestLineEntry(FID, PrevEntry->IncludeOffset); + } + if (PrevEntry) { IncludeOffset = PrevEntry->IncludeOffset; + if (FilenameID == -1) { + // An unspecified FilenameID means use the previous (or containing) + // filename if available, or the main source file otherwise. + FilenameID = PrevEntry->FilenameID; + } + } } Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind, @@ -324,8 +324,7 @@ SourceManager::~SourceManager() { ContentCacheAlloc.Deallocate(MemBufferInfos[i]); } } - for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator - I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) { + for (auto I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) { if (I->second) { I->second->~ContentCache(); ContentCacheAlloc.Deallocate(I->second); @@ -338,6 +337,7 @@ void SourceManager::clearIDTables() { LocalSLocEntryTable.clear(); LoadedSLocEntryTable.clear(); SLocEntryLoaded.clear(); + SLocEntryOffsetLoaded.clear(); LastLineNoFileIDQuery = FileID(); LastLineNoContentCache = nullptr; LastFileIDLookup = FileID(); @@ -399,8 +399,7 @@ ContentCache &SourceManager::getOrCreateContentCache(FileEntryRef FileEnt, if (OverriddenFilesInfo) { // If the file contents are overridden with contents from another file, // pass that file to ContentCache. - llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator - overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt); + auto overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt); if (overI == OverriddenFilesInfo->OverriddenFiles.end()) new (Entry) ContentCache(FileEnt); else @@ -455,13 +454,17 @@ SourceManager::AllocateLoadedSLocEntries(unsigned NumSLocEntries, SourceLocation::UIntTy TotalSize) { assert(ExternalSLocEntries && "Don't have an external sloc source"); // Make sure we're not about to run out of source locations. - if (CurrentLoadedOffset - TotalSize < NextLocalOffset) + if (CurrentLoadedOffset < TotalSize || + CurrentLoadedOffset - TotalSize < NextLocalOffset) { return std::make_pair(0, 0); + } LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries); SLocEntryLoaded.resize(LoadedSLocEntryTable.size()); + SLocEntryOffsetLoaded.resize(LoadedSLocEntryTable.size()); CurrentLoadedOffset -= TotalSize; - int ID = LoadedSLocEntryTable.size(); - return std::make_pair(-ID - 1, CurrentLoadedOffset); + int BaseID = -int(LoadedSLocEntryTable.size()) - 1; + LoadedSLocEntryAllocBegin.push_back(FileID::get(BaseID)); + return std::make_pair(BaseID, CurrentLoadedOffset); } /// As part of recovering from missing or changed content, produce a @@ -527,17 +530,6 @@ FileID SourceManager::getNextFileID(FileID FID) const { /// 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, - SourceLocation::UIntTy LoadedOffset) { - return createFileID(SourceFile->getLastRef(), IncludePos, FileCharacter, - LoadedID, LoadedOffset); -} - FileID SourceManager::createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, @@ -585,7 +577,7 @@ FileID SourceManager::createFileID(const llvm::MemoryBufferRef &Buffer, /// Get the FileID for \p SourceFile if it exists. Otherwise, create a /// new FileID for the \p SourceFile. FileID -SourceManager::getOrCreateFileID(const FileEntry *SourceFile, +SourceManager::getOrCreateFileID(FileEntryRef SourceFile, SrcMgr::CharacteristicKind FileCharacter) { FileID ID = translateFile(SourceFile); return ID.isValid() ? ID : createFileID(SourceFile, SourceLocation(), @@ -607,13 +599,14 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename, assert(!SLocEntryLoaded[Index] && "FileID already loaded"); LoadedSLocEntryTable[Index] = SLocEntry::get( LoadedOffset, FileInfo::get(IncludePos, File, FileCharacter, Filename)); - SLocEntryLoaded[Index] = true; + SLocEntryLoaded[Index] = SLocEntryOffsetLoaded[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); + Diag.Report(IncludePos, diag::err_sloc_space_too_large); + noteSLocAddressSpaceUsage(Diag); return FileID(); } LocalSLocEntryTable.push_back( @@ -629,23 +622,21 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename, return LastFileIDLookup = FID; } -SourceLocation -SourceManager::createMacroArgExpansionLoc(SourceLocation SpellingLoc, - SourceLocation ExpansionLoc, - unsigned TokLength) { +SourceLocation SourceManager::createMacroArgExpansionLoc( + SourceLocation SpellingLoc, SourceLocation ExpansionLoc, unsigned Length) { ExpansionInfo Info = ExpansionInfo::createForMacroArg(SpellingLoc, ExpansionLoc); - return createExpansionLocImpl(Info, TokLength); + return createExpansionLocImpl(Info, Length); } SourceLocation SourceManager::createExpansionLoc( SourceLocation SpellingLoc, SourceLocation ExpansionLocStart, - SourceLocation ExpansionLocEnd, unsigned TokLength, + SourceLocation ExpansionLocEnd, unsigned Length, bool ExpansionIsTokenRange, int LoadedID, SourceLocation::UIntTy LoadedOffset) { ExpansionInfo Info = ExpansionInfo::create( SpellingLoc, ExpansionLocStart, ExpansionLocEnd, ExpansionIsTokenRange); - return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset); + return createExpansionLocImpl(Info, Length, LoadedID, LoadedOffset); } SourceLocation SourceManager::createTokenSplitLoc(SourceLocation Spelling, @@ -660,7 +651,7 @@ SourceLocation SourceManager::createTokenSplitLoc(SourceLocation Spelling, SourceLocation SourceManager::createExpansionLocImpl(const ExpansionInfo &Info, - unsigned TokLength, int LoadedID, + unsigned Length, int LoadedID, SourceLocation::UIntTy LoadedOffset) { if (LoadedID < 0) { assert(LoadedID != -1 && "Loading sentinel FileID"); @@ -668,27 +659,34 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo &Info, assert(Index < LoadedSLocEntryTable.size() && "FileID out of range"); assert(!SLocEntryLoaded[Index] && "FileID already loaded"); LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info); - SLocEntryLoaded[Index] = true; + SLocEntryLoaded[Index] = SLocEntryOffsetLoaded[Index] = true; return SourceLocation::getMacroLoc(LoadedOffset); } LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info)); - assert(NextLocalOffset + TokLength + 1 > NextLocalOffset && - NextLocalOffset + TokLength + 1 <= CurrentLoadedOffset && - "Ran out of source locations!"); + if (NextLocalOffset + Length + 1 <= NextLocalOffset || + NextLocalOffset + Length + 1 > CurrentLoadedOffset) { + Diag.Report(SourceLocation(), diag::err_sloc_space_too_large); + // FIXME: call `noteSLocAddressSpaceUsage` to report details to users and + // use a source location from `Info` to point at an error. + // Currently, both cause Clang to run indefinitely, this needs to be fixed. + // FIXME: return an error instead of crashing. Returning invalid source + // locations causes compiler to run indefinitely. + llvm::report_fatal_error("ran out of source locations"); + } // See createFileID for that +1. - NextLocalOffset += TokLength + 1; - return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1)); + NextLocalOffset += Length + 1; + return SourceLocation::getMacroLoc(NextLocalOffset - (Length + 1)); } -llvm::Optional<llvm::MemoryBufferRef> -SourceManager::getMemoryBufferForFileOrNone(const FileEntry *File) { - SrcMgr::ContentCache &IR = getOrCreateContentCache(File->getLastRef()); +std::optional<llvm::MemoryBufferRef> +SourceManager::getMemoryBufferForFileOrNone(FileEntryRef File) { + SrcMgr::ContentCache &IR = getOrCreateContentCache(File); return IR.getBufferOrNone(Diag, getFileManager(), SourceLocation()); } void SourceManager::overrideFileContents( - const FileEntry *SourceFile, std::unique_ptr<llvm::MemoryBuffer> Buffer) { - SrcMgr::ContentCache &IR = getOrCreateContentCache(SourceFile->getLastRef()); + FileEntryRef SourceFile, std::unique_ptr<llvm::MemoryBuffer> Buffer) { + SrcMgr::ContentCache &IR = getOrCreateContentCache(SourceFile); IR.setBuffer(std::move(Buffer)); IR.BufferOverridden = true; @@ -697,39 +695,43 @@ void SourceManager::overrideFileContents( } void SourceManager::overrideFileContents(const FileEntry *SourceFile, - const FileEntry *NewFile) { - assert(SourceFile->getSize() == NewFile->getSize() && + FileEntryRef NewFile) { + assert(SourceFile->getSize() == NewFile.getSize() && "Different sizes, use the FileManager to create a virtual file with " "the correct size"); - assert(FileInfos.count(SourceFile) == 0 && + assert(FileInfos.find_as(SourceFile) == FileInfos.end() && "This function should be called at the initialization stage, before " "any parsing occurs."); - getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile; + // FileEntryRef is not default-constructible. + auto Pair = getOverriddenFilesInfo().OverriddenFiles.insert( + std::make_pair(SourceFile, NewFile)); + if (!Pair.second) + Pair.first->second = NewFile; } -Optional<FileEntryRef> +OptionalFileEntryRef SourceManager::bypassFileContentsOverride(FileEntryRef File) { assert(isFileOverridden(&File.getFileEntry())); - llvm::Optional<FileEntryRef> BypassFile = FileMgr.getBypassFile(File); + OptionalFileEntryRef BypassFile = FileMgr.getBypassFile(File); // If the file can't be found in the FS, give up. if (!BypassFile) - return None; + return std::nullopt; (void)getOrCreateContentCache(*BypassFile); return BypassFile; } -void SourceManager::setFileIsTransient(const FileEntry *File) { - getOrCreateContentCache(File->getLastRef()).IsTransient = true; +void SourceManager::setFileIsTransient(FileEntryRef File) { + getOrCreateContentCache(File).IsTransient = true; } -Optional<StringRef> +std::optional<StringRef> SourceManager::getNonBuiltinFilenameForID(FileID FID) const { if (const SrcMgr::SLocEntry *Entry = getSLocEntryForFile(FID)) if (Entry->getFile().getContentCache().OrigEntry) return Entry->getFile().getName(); - return None; + return std::nullopt; } StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const { @@ -739,19 +741,19 @@ StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const { return B ? *B : "<<<<<INVALID SOURCE LOCATION>>>>>"; } -llvm::Optional<StringRef> +std::optional<StringRef> SourceManager::getBufferDataIfLoaded(FileID FID) const { if (const SrcMgr::SLocEntry *Entry = getSLocEntryForFile(FID)) return Entry->getFile().getContentCache().getBufferDataIfLoaded(); - return None; + return std::nullopt; } -llvm::Optional<StringRef> SourceManager::getBufferDataOrNone(FileID FID) const { +std::optional<StringRef> SourceManager::getBufferDataOrNone(FileID FID) const { if (const SrcMgr::SLocEntry *Entry = getSLocEntryForFile(FID)) if (auto B = Entry->getFile().getContentCache().getBufferOrNone( Diag, getFileManager(), SourceLocation())) return B->getBuffer(); - return None; + return std::nullopt; } //===----------------------------------------------------------------------===// @@ -792,24 +794,28 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const { // See if this is near the file point - worst case we start scanning from the // most newly created FileID. - const SrcMgr::SLocEntry *I; - if (LastFileIDLookup.ID < 0 || - LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) { - // Neither loc prunes our search. - I = LocalSLocEntryTable.end(); - } else { - // Perhaps it is near the file point. - I = LocalSLocEntryTable.begin()+LastFileIDLookup.ID; + // LessIndex - This is the lower bound of the range that we're searching. + // We know that the offset corresponding to the FileID is less than + // SLocOffset. + unsigned LessIndex = 0; + // upper bound of the search range. + unsigned GreaterIndex = LocalSLocEntryTable.size(); + if (LastFileIDLookup.ID >= 0) { + // Use the LastFileIDLookup to prune the search space. + if (LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) + LessIndex = LastFileIDLookup.ID; + else + GreaterIndex = LastFileIDLookup.ID; } - // Find the FileID that contains this. "I" is an iterator that points to a - // FileID whose offset is known to be larger than SLocOffset. + // Find the FileID that contains this. unsigned NumProbes = 0; while (true) { - --I; - if (I->getOffset() <= SLocOffset) { - FileID Res = FileID::get(int(I - LocalSLocEntryTable.begin())); + --GreaterIndex; + assert(GreaterIndex < LocalSLocEntryTable.size()); + if (LocalSLocEntryTable[GreaterIndex].getOffset() <= SLocOffset) { + FileID Res = FileID::get(int(GreaterIndex)); // Remember it. We have good locality across FileID lookups. LastFileIDLookup = Res; NumLinearScans += NumProbes+1; @@ -819,13 +825,6 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const { break; } - // Convert "I" back into an index. We know that it is an entry whose index is - // larger than the offset we are looking for. - unsigned GreaterIndex = I - LocalSLocEntryTable.begin(); - // LessIndex - This is the lower bound of the range that we're searching. - // We know that the offset corresponding to the FileID is is less than - // SLocOffset. - unsigned LessIndex = 0; NumProbes = 0; while (true) { unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex; @@ -862,74 +861,12 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const { /// This function knows that the SourceLocation is in a loaded buffer, not a /// local one. FileID SourceManager::getFileIDLoaded(SourceLocation::UIntTy SLocOffset) const { - // Sanity checking, otherwise a bug may lead to hanging in release build. if (SLocOffset < CurrentLoadedOffset) { assert(0 && "Invalid SLocOffset or bad function choice"); return FileID(); } - // Essentially the same as the local case, but the loaded array is sorted - // in the other direction. - - // First do a linear scan from the last lookup position, if possible. - unsigned I; - int LastID = LastFileIDLookup.ID; - if (LastID >= 0 || getLoadedSLocEntryByID(LastID).getOffset() < SLocOffset) - I = 0; - else - I = (-LastID - 2) + 1; - - unsigned NumProbes; - for (NumProbes = 0; NumProbes < 8; ++NumProbes, ++I) { - // Make sure the entry is loaded! - const SrcMgr::SLocEntry &E = getLoadedSLocEntry(I); - if (E.getOffset() <= SLocOffset) { - FileID Res = FileID::get(-int(I) - 2); - LastFileIDLookup = Res; - NumLinearScans += NumProbes + 1; - return Res; - } - } - - // Linear scan failed. Do the binary search. Note the reverse sorting of the - // table: GreaterIndex is the one where the offset is greater, which is - // actually a lower index! - unsigned GreaterIndex = I; - unsigned LessIndex = LoadedSLocEntryTable.size(); - NumProbes = 0; - while (true) { - ++NumProbes; - unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex; - const SrcMgr::SLocEntry &E = getLoadedSLocEntry(MiddleIndex); - if (E.getOffset() == 0) - return FileID(); // invalid entry. - - ++NumProbes; - - if (E.getOffset() > SLocOffset) { - // Sanity checking, otherwise a bug may lead to hanging in release build. - if (GreaterIndex == MiddleIndex) { - assert(0 && "binary search missed the entry"); - return FileID(); - } - GreaterIndex = MiddleIndex; - continue; - } - - if (isOffsetInFileID(FileID::get(-int(MiddleIndex) - 2), SLocOffset)) { - FileID Res = FileID::get(-int(MiddleIndex) - 2); - LastFileIDLookup = Res; - NumBinaryProbes += NumProbes; - return Res; - } - - // Sanity checking, otherwise a bug may lead to hanging in release build. - if (LessIndex == MiddleIndex) { - assert(0 && "binary search missed the entry"); - return FileID(); - } - LessIndex = MiddleIndex; - } + return FileID::get(ExternalSLocEntries->getSLocEntryID(SLocOffset)); } SourceLocation SourceManager:: @@ -1016,7 +953,7 @@ SourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{ /// Return the filename of the file containing a SourceLocation. StringRef SourceManager::getFilename(SourceLocation SpellingLoc) const { - if (const FileEntry *F = getFileEntryForID(getFileID(SpellingLoc))) + if (OptionalFileEntryRef F = getFileEntryRefForID(getFileID(SpellingLoc))) return F->getName(); return StringRef(); } @@ -1169,7 +1106,7 @@ const char *SourceManager::getCharacterData(SourceLocation SL, return "<<<<INVALID BUFFER>>>>"; } - llvm::Optional<llvm::MemoryBufferRef> Buffer = + std::optional<llvm::MemoryBufferRef> Buffer = Entry.getFile().getContentCache().getBufferOrNone(Diag, getFileManager(), SourceLocation()); if (Invalid) @@ -1182,7 +1119,7 @@ const char *SourceManager::getCharacterData(SourceLocation SL, /// this is significantly cheaper to compute than the line number. unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos, bool *Invalid) const { - llvm::Optional<llvm::MemoryBufferRef> MemBuf = getBufferOrNone(FID); + std::optional<llvm::MemoryBufferRef> MemBuf = getBufferOrNone(FID); if (Invalid) *Invalid = !MemBuf; @@ -1278,22 +1215,21 @@ LineOffsetMapping LineOffsetMapping::get(llvm::MemoryBufferRef Buffer, // Line #1 starts at char 0. LineOffsets.push_back(0); - const unsigned char *Buf = (const unsigned char *)Buffer.getBufferStart(); + const unsigned char *Start = (const unsigned char *)Buffer.getBufferStart(); const unsigned char *End = (const unsigned char *)Buffer.getBufferEnd(); - const std::size_t BufLen = End - Buf; + const unsigned char *Buf = Start; - unsigned I = 0; uint64_t Word; // scan sizeof(Word) bytes at a time for new lines. // This is much faster than scanning each byte independently. - if (BufLen > sizeof(Word)) { + if ((unsigned long)(End - Start) > sizeof(Word)) { do { - Word = llvm::support::endian::read64(Buf + I, llvm::support::little); + Word = llvm::support::endian::read64(Buf, llvm::endianness::little); // no new line => jump over sizeof(Word) bytes. auto Mask = likelyhasbetween(Word, '\n', '\r'); if (!Mask) { - I += sizeof(Word); + Buf += sizeof(Word); continue; } @@ -1301,33 +1237,35 @@ LineOffsetMapping LineOffsetMapping::get(llvm::MemoryBufferRef Buffer, // in [\n, \r + 1 [ // Scan for the next newline - it's very likely there's one. - unsigned N = - llvm::countTrailingZeros(Mask) - 7; // -7 because 0x80 is the marker + unsigned N = llvm::countr_zero(Mask) - 7; // -7 because 0x80 is the marker Word >>= N; - I += N / 8 + 1; + Buf += N / 8 + 1; unsigned char Byte = Word; - if (Byte == '\n') { - LineOffsets.push_back(I); - } else if (Byte == '\r') { + switch (Byte) { + case '\r': // If this is \r\n, skip both characters. - if (Buf[I] == '\n') - ++I; - LineOffsets.push_back(I); - } - } while (I < BufLen - sizeof(Word) - 1); + if (*Buf == '\n') { + ++Buf; + } + [[fallthrough]]; + case '\n': + LineOffsets.push_back(Buf - Start); + }; + } while (Buf < End - sizeof(Word) - 1); } // Handle tail using a regular check. - while (I < BufLen) { - if (Buf[I] == '\n') { - LineOffsets.push_back(I + 1); - } else if (Buf[I] == '\r') { + while (Buf < End) { + if (*Buf == '\n') { + LineOffsets.push_back(Buf - Start + 1); + } else if (*Buf == '\r') { // If this is \r\n, skip both characters. - if (I + 1 < BufLen && Buf[I + 1] == '\n') - ++I; - LineOffsets.push_back(I + 1); + if (Buf + 1 < End && Buf[1] == '\n') { + ++Buf; + } + LineOffsets.push_back(Buf - Start + 1); } - ++I; + ++Buf; } return LineOffsetMapping(LineOffsets, Alloc); @@ -1368,9 +1306,9 @@ unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos, } // If this is the first use of line information for this buffer, compute the - /// SourceLineCache for it on demand. + // SourceLineCache for it on demand. if (!Content->SourceLineCache) { - llvm::Optional<llvm::MemoryBufferRef> Buffer = + std::optional<llvm::MemoryBufferRef> Buffer = Content->getBufferOrNone(Diag, getFileManager(), SourceLocation()); if (Invalid) *Invalid = !Buffer; @@ -1720,7 +1658,7 @@ SourceLocation SourceManager::translateLineCol(FileID FID, // If this is the first use of line information for this buffer, compute the // SourceLineCache for it on demand. - llvm::Optional<llvm::MemoryBufferRef> Buffer = + std::optional<llvm::MemoryBufferRef> Buffer = Content->getBufferOrNone(Diag, getFileManager()); if (!Buffer) return SourceLocation(); @@ -1797,11 +1735,11 @@ void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache, if (Entry.getFile().NumCreatedFIDs) ID += Entry.getFile().NumCreatedFIDs - 1 /*because of next ++ID*/; continue; - } 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; } + // If file was included but not from FID, there is no more files/macros + // that may be "contained" in this file. + if (IncludeLoc.isValid()) + return; continue; } @@ -1973,14 +1911,39 @@ SourceManager::getDecomposedIncludedLoc(FileID FID) const { return DecompLoc; } +bool SourceManager::isInTheSameTranslationUnitImpl( + const std::pair<FileID, unsigned> &LOffs, + const std::pair<FileID, unsigned> &ROffs) const { + // If one is local while the other is loaded. + if (isLoadedFileID(LOffs.first) != isLoadedFileID(ROffs.first)) + return false; + + if (isLoadedFileID(LOffs.first) && isLoadedFileID(ROffs.first)) { + auto FindSLocEntryAlloc = [this](FileID FID) { + // Loaded FileIDs are negative, we store the lowest FileID from each + // allocation, later allocations have lower FileIDs. + return llvm::lower_bound(LoadedSLocEntryAllocBegin, FID, + std::greater<FileID>{}); + }; + + // If both are loaded from different AST files. + if (FindSLocEntryAlloc(LOffs.first) != FindSLocEntryAlloc(ROffs.first)) + return false; + } + + return true; +} + /// Given a decomposed source location, move it up the include/expansion stack -/// to the parent source location. If this is possible, return the decomposed -/// version of the parent in Loc and return false. If Loc is the top-level -/// entry, return true and don't modify it. -static bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc, - const SourceManager &SM) { +/// to the parent source location within the same translation unit. If this is +/// possible, return the decomposed version of the parent in Loc and return +/// false. If Loc is a top-level entry, return true and don't modify it. +static bool +MoveUpTranslationUnitIncludeHierarchy(std::pair<FileID, unsigned> &Loc, + const SourceManager &SM) { std::pair<FileID, unsigned> UpperLoc = SM.getDecomposedIncludedLoc(Loc.first); - if (UpperLoc.first.isInvalid()) + if (UpperLoc.first.isInvalid() || + !SM.isInTheSameTranslationUnitImpl(UpperLoc, Loc)) return true; // We reached the top. Loc = UpperLoc; @@ -1994,6 +1957,7 @@ InBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID, // This is a magic number for limiting the cache size. It was experimentally // derived from a small Objective-C project (where the cache filled // out to ~250 items). We can make it larger if necessary. + // FIXME: this is almost certainly full these days. Use an LRU cache? enum { MagicCacheSize = 300 }; IsBeforeInTUCacheKey Key(LFID, RFID); @@ -2002,7 +1966,7 @@ InBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID, // use. When they update the value, the cache will get automatically // updated as well. if (IBTUCache.size() < MagicCacheSize) - return IBTUCache[Key]; + return IBTUCache.try_emplace(Key, LFID, RFID).first->second; // Otherwise, do a lookup that will not construct a new value. InBeforeInTUCache::iterator I = IBTUCache.find(Key); @@ -2010,6 +1974,7 @@ InBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID, return I->second; // Fall back to the overflow value. + IBTUCacheOverflow.setQueryFIDs(LFID, RFID); return IBTUCacheOverflow; } @@ -2034,45 +1999,18 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, std::pair<bool, bool> InSameTU = isInTheSameTranslationUnit(LOffs, ROffs); if (InSameTU.first) return InSameTU.second; - - // If we arrived here, the location is either in a built-ins buffer or - // associated with global inline asm. PR5662 and PR22576 are examples. - - StringRef LB = getBufferOrFake(LOffs.first).getBufferIdentifier(); - StringRef RB = getBufferOrFake(ROffs.first).getBufferIdentifier(); - bool LIsBuiltins = LB == "<built-in>"; - bool RIsBuiltins = RB == "<built-in>"; - // Sort built-in before non-built-in. - if (LIsBuiltins || RIsBuiltins) { - if (LIsBuiltins != RIsBuiltins) - return LIsBuiltins; - // Both are in built-in buffers, but from different files. We just claim that - // lower IDs come first. - return LOffs.first < ROffs.first; - } - bool LIsAsm = LB == "<inline asm>"; - bool RIsAsm = RB == "<inline asm>"; - // Sort assembler after built-ins, but before the rest. - if (LIsAsm || RIsAsm) { - if (LIsAsm != RIsAsm) - return RIsAsm; - assert(LOffs.first == ROffs.first); - return false; - } - bool LIsScratch = LB == "<scratch space>"; - bool RIsScratch = RB == "<scratch space>"; - // Sort scratch after inline asm, but before the rest. - if (LIsScratch || RIsScratch) { - if (LIsScratch != RIsScratch) - return LIsScratch; - return LOffs.second < ROffs.second; - } - llvm_unreachable("Unsortable locations found"); + // TODO: This should be unreachable, but some clients are calling this + // function before making sure LHS and RHS are in the same TU. + return LOffs.first < ROffs.first; } std::pair<bool, bool> SourceManager::isInTheSameTranslationUnit( std::pair<FileID, unsigned> &LOffs, std::pair<FileID, unsigned> &ROffs) const { + // If the source locations are not in the same TU, return early. + if (!isInTheSameTranslationUnitImpl(LOffs, ROffs)) + return std::make_pair(false, false); + // If the source locations are in the same file, just compare offsets. if (LOffs.first == ROffs.first) return std::make_pair(true, LOffs.second < ROffs.second); @@ -2084,58 +2022,115 @@ std::pair<bool, bool> SourceManager::isInTheSameTranslationUnit( // If we are comparing a source location with multiple locations in the same // file, we get a big win by caching the result. - if (IsBeforeInTUCache.isCacheValid(LOffs.first, ROffs.first)) + if (IsBeforeInTUCache.isCacheValid()) return std::make_pair( true, IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second)); - // Okay, we missed in the cache, start updating the cache for this query. - IsBeforeInTUCache.setQueryFIDs(LOffs.first, ROffs.first, - /*isLFIDBeforeRFID=*/LOffs.first.ID < ROffs.first.ID); - + // Okay, we missed in the cache, we'll compute the answer and populate it. // We need to find the common ancestor. The only way of doing this is to // build the complete include chain for one and then walking up the chain // of the other looking for a match. - // We use a map from FileID to Offset to store the chain. Easier than writing - // a custom set hash info that only depends on the first part of a pair. - using LocSet = llvm::SmallDenseMap<FileID, unsigned, 16>; - LocSet LChain; + + // A location within a FileID on the path up from LOffs to the main file. + struct Entry { + std::pair<FileID, unsigned> DecomposedLoc; // FileID redundant, but clearer. + FileID ChildFID; // Used for breaking ties. Invalid for the initial loc. + }; + llvm::SmallDenseMap<FileID, Entry, 16> LChain; + + FileID LChild; do { - LChain.insert(LOffs); + LChain.try_emplace(LOffs.first, Entry{LOffs, LChild}); // We catch the case where LOffs is in a file included by ROffs and // quit early. The other way round unfortunately remains suboptimal. - } while (LOffs.first != ROffs.first && !MoveUpIncludeHierarchy(LOffs, *this)); - LocSet::iterator I; - while((I = LChain.find(ROffs.first)) == LChain.end()) { - if (MoveUpIncludeHierarchy(ROffs, *this)) - break; // Met at topmost file. + if (LOffs.first == ROffs.first) + break; + LChild = LOffs.first; + } while (!MoveUpTranslationUnitIncludeHierarchy(LOffs, *this)); + + FileID RChild; + do { + auto LIt = LChain.find(ROffs.first); + if (LIt != LChain.end()) { + // Compare the locations within the common file and cache them. + LOffs = LIt->second.DecomposedLoc; + LChild = LIt->second.ChildFID; + // The relative order of LChild and RChild is a tiebreaker when + // - locs expand to the same location (occurs in macro arg expansion) + // - one loc is a parent of the other (we consider the parent as "first") + // For the parent entry to be first, its invalid child file ID must + // compare smaller to the valid child file ID of the other entry. + // However loaded FileIDs are <0, so we perform *unsigned* comparison! + // This changes the relative order of local vs loaded FileIDs, but it + // doesn't matter as these are never mixed in macro expansion. + unsigned LChildID = LChild.ID; + unsigned RChildID = RChild.ID; + assert(((LOffs.second != ROffs.second) || + (LChildID == 0 || RChildID == 0) || + isInSameSLocAddrSpace(getComposedLoc(LChild, 0), + getComposedLoc(RChild, 0), nullptr)) && + "Mixed local/loaded FileIDs with same include location?"); + IsBeforeInTUCache.setCommonLoc(LOffs.first, LOffs.second, ROffs.second, + LChildID < RChildID); + return std::make_pair( + true, IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second)); + } + RChild = ROffs.first; + } while (!MoveUpTranslationUnitIncludeHierarchy(ROffs, *this)); + + // If we found no match, the location is either in a built-ins buffer or + // associated with global inline asm. PR5662 and PR22576 are examples. + + StringRef LB = getBufferOrFake(LOffs.first).getBufferIdentifier(); + StringRef RB = getBufferOrFake(ROffs.first).getBufferIdentifier(); + + bool LIsBuiltins = LB == "<built-in>"; + bool RIsBuiltins = RB == "<built-in>"; + // Sort built-in before non-built-in. + if (LIsBuiltins || RIsBuiltins) { + if (LIsBuiltins != RIsBuiltins) + return std::make_pair(true, LIsBuiltins); + // Both are in built-in buffers, but from different files. We just claim + // that lower IDs come first. + return std::make_pair(true, LOffs.first < ROffs.first); } - if (I != LChain.end()) - LOffs = *I; - // If we exited because we found a nearest common ancestor, compare the - // locations within the common file and cache them. - if (LOffs.first == ROffs.first) { - IsBeforeInTUCache.setCommonLoc(LOffs.first, LOffs.second, ROffs.second); - return std::make_pair( - true, IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second)); + bool LIsAsm = LB == "<inline asm>"; + bool RIsAsm = RB == "<inline asm>"; + // Sort assembler after built-ins, but before the rest. + if (LIsAsm || RIsAsm) { + if (LIsAsm != RIsAsm) + return std::make_pair(true, RIsAsm); + assert(LOffs.first == ROffs.first); + return std::make_pair(true, false); + } + + bool LIsScratch = LB == "<scratch space>"; + bool RIsScratch = RB == "<scratch space>"; + // Sort scratch after inline asm, but before the rest. + if (LIsScratch || RIsScratch) { + if (LIsScratch != RIsScratch) + return std::make_pair(true, LIsScratch); + return std::make_pair(true, LOffs.second < ROffs.second); } - // Clear the lookup cache, it depends on a common location. - IsBeforeInTUCache.clear(); - return std::make_pair(false, false); + + llvm_unreachable("Unsortable locations found"); } void SourceManager::PrintStats() const { llvm::errs() << "\n*** Source Manager Stats:\n"; llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size() << " mem buffers mapped.\n"; - llvm::errs() << LocalSLocEntryTable.size() << " local SLocEntry's allocated (" + llvm::errs() << LocalSLocEntryTable.size() << " local SLocEntries allocated (" << llvm::capacity_in_bytes(LocalSLocEntryTable) - << " bytes of capacity), " - << NextLocalOffset << "B of Sloc address space used.\n"; + << " bytes of capacity), " << NextLocalOffset + << "B of SLoc address space used.\n"; llvm::errs() << LoadedSLocEntryTable.size() - << " loaded SLocEntries allocated, " + << " loaded SLocEntries allocated (" + << llvm::capacity_in_bytes(LoadedSLocEntryTable) + << " bytes of capacity), " << MaxLoadedOffset - CurrentLoadedOffset - << "B of Sloc address space used.\n"; + << "B of SLoc address space used.\n"; unsigned NumLineNumsComputed = 0; unsigned NumFileBytesMapped = 0; @@ -2156,7 +2151,7 @@ LLVM_DUMP_METHOD void SourceManager::dump() const { llvm::raw_ostream &out = llvm::errs(); auto DumpSLocEntry = [&](int ID, const SrcMgr::SLocEntry &Entry, - llvm::Optional<SourceLocation::UIntTy> NextStart) { + std::optional<SourceLocation::UIntTy> NextStart) { out << "SLocEntry <FileID " << ID << "> " << (Entry.isFile() ? "file" : "expansion") << " <SourceLocation " << Entry.getOffset() << ":"; if (NextStart) @@ -2196,15 +2191,103 @@ LLVM_DUMP_METHOD void SourceManager::dump() const { : LocalSLocEntryTable[ID + 1].getOffset()); } // Dump loaded SLocEntries. - llvm::Optional<SourceLocation::UIntTy> NextStart; + std::optional<SourceLocation::UIntTy> NextStart; for (unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) { int ID = -(int)Index - 2; if (SLocEntryLoaded[Index]) { DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart); NextStart = LoadedSLocEntryTable[Index].getOffset(); } else { - NextStart = None; + NextStart = std::nullopt; + } + } +} + +void SourceManager::noteSLocAddressSpaceUsage( + DiagnosticsEngine &Diag, std::optional<unsigned> MaxNotes) const { + struct Info { + // A location where this file was entered. + SourceLocation Loc; + // Number of times this FileEntry was entered. + unsigned Inclusions = 0; + // Size usage from the file itself. + uint64_t DirectSize = 0; + // Total size usage from the file and its macro expansions. + uint64_t TotalSize = 0; + }; + using UsageMap = llvm::MapVector<const FileEntry*, Info>; + + UsageMap Usage; + uint64_t CountedSize = 0; + + auto AddUsageForFileID = [&](FileID ID) { + // The +1 here is because getFileIDSize doesn't include the extra byte for + // the one-past-the-end location. + unsigned Size = getFileIDSize(ID) + 1; + + // Find the file that used this address space, either directly or by + // macro expansion. + SourceLocation FileStart = getFileLoc(getComposedLoc(ID, 0)); + FileID FileLocID = getFileID(FileStart); + const FileEntry *Entry = getFileEntryForID(FileLocID); + + Info &EntryInfo = Usage[Entry]; + if (EntryInfo.Loc.isInvalid()) + EntryInfo.Loc = FileStart; + if (ID == FileLocID) { + ++EntryInfo.Inclusions; + EntryInfo.DirectSize += Size; } + EntryInfo.TotalSize += Size; + CountedSize += Size; + }; + + // Loaded SLocEntries have indexes counting downwards from -2. + for (size_t Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) { + AddUsageForFileID(FileID::get(-2 - Index)); + } + // Local SLocEntries have indexes counting upwards from 0. + for (size_t Index = 0; Index != LocalSLocEntryTable.size(); ++Index) { + AddUsageForFileID(FileID::get(Index)); + } + + // Sort the usage by size from largest to smallest. Break ties by raw source + // location. + auto SortedUsage = Usage.takeVector(); + auto Cmp = [](const UsageMap::value_type &A, const UsageMap::value_type &B) { + return A.second.TotalSize > B.second.TotalSize || + (A.second.TotalSize == B.second.TotalSize && + A.second.Loc < B.second.Loc); + }; + auto SortedEnd = SortedUsage.end(); + if (MaxNotes && SortedUsage.size() > *MaxNotes) { + SortedEnd = SortedUsage.begin() + *MaxNotes; + std::nth_element(SortedUsage.begin(), SortedEnd, SortedUsage.end(), Cmp); + } + std::sort(SortedUsage.begin(), SortedEnd, Cmp); + + // Produce note on sloc address space usage total. + uint64_t LocalUsage = NextLocalOffset; + uint64_t LoadedUsage = MaxLoadedOffset - CurrentLoadedOffset; + int UsagePercent = static_cast<int>(100.0 * double(LocalUsage + LoadedUsage) / + MaxLoadedOffset); + Diag.Report(SourceLocation(), diag::note_total_sloc_usage) + << LocalUsage << LoadedUsage << (LocalUsage + LoadedUsage) << UsagePercent; + + // Produce notes on sloc address space usage for each file with a high usage. + uint64_t ReportedSize = 0; + for (auto &[Entry, FileInfo] : + llvm::make_range(SortedUsage.begin(), SortedEnd)) { + Diag.Report(FileInfo.Loc, diag::note_file_sloc_usage) + << FileInfo.Inclusions << FileInfo.DirectSize + << (FileInfo.TotalSize - FileInfo.DirectSize); + ReportedSize += FileInfo.TotalSize; + } + + // Describe any remaining usage not reported in the per-file usage. + if (ReportedSize != CountedSize) { + Diag.Report(SourceLocation(), diag::note_file_misc_sloc_usage) + << (SortedUsage.end() - SortedEnd) << CountedSize - ReportedSize; } } @@ -2231,11 +2314,11 @@ SourceManager::MemoryBufferSizes SourceManager::getMemoryBufferSizes() const { } size_t SourceManager::getDataStructureSizes() const { - size_t size = llvm::capacity_in_bytes(MemBufferInfos) - + llvm::capacity_in_bytes(LocalSLocEntryTable) - + llvm::capacity_in_bytes(LoadedSLocEntryTable) - + llvm::capacity_in_bytes(SLocEntryLoaded) - + llvm::capacity_in_bytes(FileInfos); + size_t size = llvm::capacity_in_bytes(MemBufferInfos) + + llvm::capacity_in_bytes(LocalSLocEntryTable) + + llvm::capacity_in_bytes(LoadedSLocEntryTable) + + llvm::capacity_in_bytes(SLocEntryLoaded) + + llvm::capacity_in_bytes(FileInfos); if (OverriddenFilesInfo) size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles); @@ -2263,8 +2346,9 @@ SourceManagerForFile::SourceManagerForFile(StringRef FileName, IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), new DiagnosticOptions); SourceMgr = std::make_unique<SourceManager>(*Diagnostics, *FileMgr); - FileID ID = SourceMgr->createFileID(*FileMgr->getFile(FileName), - SourceLocation(), clang::SrcMgr::C_User); + FileEntryRef FE = llvm::cantFail(FileMgr->getFileRef(FileName)); + FileID ID = + SourceMgr->createFileID(FE, SourceLocation(), clang::SrcMgr::C_User); assert(ID.isValid()); SourceMgr->setMainFileID(ID); } diff --git a/contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp b/contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp new file mode 100644 index 000000000000..e39e4de9d42d --- /dev/null +++ b/contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp @@ -0,0 +1,136 @@ +//=== SourceMgrAdapter.cpp - SourceMgr to SourceManager Adapter -----------===// +// +// 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 adapter that maps diagnostics from llvm::SourceMgr +// to Clang's SourceManager. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/SourceMgrAdapter.h" +#include "clang/Basic/Diagnostic.h" + +using namespace clang; + +void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag, + void *Context) { + static_cast<SourceMgrAdapter *>(Context)->handleDiag(Diag); +} + +SourceMgrAdapter::SourceMgrAdapter(SourceManager &SM, + DiagnosticsEngine &Diagnostics, + unsigned ErrorDiagID, unsigned WarningDiagID, + unsigned NoteDiagID, + OptionalFileEntryRef DefaultFile) + : SrcMgr(SM), Diagnostics(Diagnostics), ErrorDiagID(ErrorDiagID), + WarningDiagID(WarningDiagID), NoteDiagID(NoteDiagID), + DefaultFile(DefaultFile) {} + +SourceMgrAdapter::~SourceMgrAdapter() {} + +SourceLocation SourceMgrAdapter::mapLocation(const llvm::SourceMgr &LLVMSrcMgr, + llvm::SMLoc Loc) { + // Map invalid locations. + if (!Loc.isValid()) + return SourceLocation(); + + // Find the buffer containing the location. + unsigned BufferID = LLVMSrcMgr.FindBufferContainingLoc(Loc); + if (!BufferID) + return SourceLocation(); + + // If we haven't seen this buffer before, copy it over. + auto Buffer = LLVMSrcMgr.getMemoryBuffer(BufferID); + auto KnownBuffer = FileIDMapping.find(std::make_pair(&LLVMSrcMgr, BufferID)); + if (KnownBuffer == FileIDMapping.end()) { + FileID FileID; + if (DefaultFile) { + // Map to the default file. + FileID = SrcMgr.getOrCreateFileID(*DefaultFile, SrcMgr::C_User); + + // Only do this once. + DefaultFile = std::nullopt; + } else { + // Make a copy of the memory buffer. + StringRef bufferName = Buffer->getBufferIdentifier(); + auto bufferCopy = std::unique_ptr<llvm::MemoryBuffer>( + llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(), + bufferName)); + + // Add this memory buffer to the Clang source manager. + FileID = SrcMgr.createFileID(std::move(bufferCopy)); + } + + // Save the mapping. + KnownBuffer = FileIDMapping + .insert(std::make_pair( + std::make_pair(&LLVMSrcMgr, BufferID), FileID)) + .first; + } + + // Translate the offset into the file. + unsigned Offset = Loc.getPointer() - Buffer->getBufferStart(); + return SrcMgr.getLocForStartOfFile(KnownBuffer->second) + .getLocWithOffset(Offset); +} + +SourceRange SourceMgrAdapter::mapRange(const llvm::SourceMgr &LLVMSrcMgr, + llvm::SMRange Range) { + if (!Range.isValid()) + return SourceRange(); + + SourceLocation Start = mapLocation(LLVMSrcMgr, Range.Start); + SourceLocation End = mapLocation(LLVMSrcMgr, Range.End); + return SourceRange(Start, End); +} + +void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag) { + // Map the location. + SourceLocation Loc; + if (auto *LLVMSrcMgr = Diag.getSourceMgr()) + Loc = mapLocation(*LLVMSrcMgr, Diag.getLoc()); + + // Extract the message. + StringRef Message = Diag.getMessage(); + + // Map the diagnostic kind. + unsigned DiagID; + switch (Diag.getKind()) { + case llvm::SourceMgr::DK_Error: + DiagID = ErrorDiagID; + break; + + case llvm::SourceMgr::DK_Warning: + DiagID = WarningDiagID; + break; + + case llvm::SourceMgr::DK_Remark: + llvm_unreachable("remarks not implemented"); + + case llvm::SourceMgr::DK_Note: + DiagID = NoteDiagID; + break; + } + + // Report the diagnostic. + DiagnosticBuilder Builder = Diagnostics.Report(Loc, DiagID) << Message; + + if (auto *LLVMSrcMgr = Diag.getSourceMgr()) { + // Translate ranges. + SourceLocation StartOfLine = Loc.getLocWithOffset(-Diag.getColumnNo()); + for (auto Range : Diag.getRanges()) { + Builder << SourceRange(StartOfLine.getLocWithOffset(Range.first), + StartOfLine.getLocWithOffset(Range.second)); + } + + // Translate Fix-Its. + for (const llvm::SMFixIt &FixIt : Diag.getFixIts()) { + CharSourceRange Range(mapRange(*LLVMSrcMgr, FixIt.getRange()), false); + Builder << FixItHint::CreateReplacement(Range, FixIt.getText()); + } + } +} diff --git a/contrib/llvm-project/clang/lib/Basic/Stack.cpp b/contrib/llvm-project/clang/lib/Basic/Stack.cpp index 5e4750931500..aa15d8e66950 100644 --- a/contrib/llvm-project/clang/lib/Basic/Stack.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Stack.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/Stack.h" -#include "llvm/ADT/Optional.h" #include "llvm/Support/CrashRecoveryContext.h" #ifdef _MSC_VER diff --git a/contrib/llvm-project/clang/lib/Basic/TargetID.cpp b/contrib/llvm-project/clang/lib/Basic/TargetID.cpp index 59d416f0e015..3c06d9bad1dc 100644 --- a/contrib/llvm-project/clang/lib/Basic/TargetID.cpp +++ b/contrib/llvm-project/clang/lib/Basic/TargetID.cpp @@ -8,14 +8,15 @@ #include "clang/Basic/TargetID.h" #include "llvm/ADT/SmallSet.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Support/TargetParser.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/TargetParser.h" +#include "llvm/TargetParser/Triple.h" #include <map> +#include <optional> namespace clang { -static const llvm::SmallVector<llvm::StringRef, 4> +static llvm::SmallVector<llvm::StringRef, 4> getAllPossibleAMDGPUTargetIDFeatures(const llvm::Triple &T, llvm::StringRef Proc) { // Entries in returned vector should be in alphabetical order. @@ -33,7 +34,7 @@ getAllPossibleAMDGPUTargetIDFeatures(const llvm::Triple &T, return Ret; } -const llvm::SmallVector<llvm::StringRef, 4> +llvm::SmallVector<llvm::StringRef, 4> getAllPossibleTargetIDFeatures(const llvm::Triple &T, llvm::StringRef Processor) { llvm::SmallVector<llvm::StringRef, 4> Ret; @@ -62,7 +63,7 @@ llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, // A target ID is a processor name followed by a list of target features // delimited by colon. Each target feature is a string post-fixed by a plus // or minus sign, e.g. gfx908:sramecc+:xnack-. -static llvm::Optional<llvm::StringRef> +static std::optional<llvm::StringRef> parseTargetIDWithFormatCheckingOnly(llvm::StringRef TargetID, llvm::StringMap<bool> *FeatureMap) { llvm::StringRef Processor; @@ -73,7 +74,7 @@ parseTargetIDWithFormatCheckingOnly(llvm::StringRef TargetID, auto Split = TargetID.split(':'); Processor = Split.first; if (Processor.empty()) - return llvm::None; + return std::nullopt; auto Features = Split.second; if (Features.empty()) @@ -88,31 +89,30 @@ parseTargetIDWithFormatCheckingOnly(llvm::StringRef TargetID, auto Sign = Splits.first.back(); auto Feature = Splits.first.drop_back(); if (Sign != '+' && Sign != '-') - return llvm::None; + return std::nullopt; bool IsOn = Sign == '+'; auto Loc = FeatureMap->find(Feature); // Each feature can only show up at most once in target ID. if (Loc != FeatureMap->end()) - return llvm::None; + return std::nullopt; (*FeatureMap)[Feature] = IsOn; Features = Splits.second; } return Processor; } -llvm::Optional<llvm::StringRef> +std::optional<llvm::StringRef> parseTargetID(const llvm::Triple &T, llvm::StringRef TargetID, llvm::StringMap<bool> *FeatureMap) { auto OptionalProcessor = parseTargetIDWithFormatCheckingOnly(TargetID, FeatureMap); if (!OptionalProcessor) - return llvm::None; + return std::nullopt; - llvm::StringRef Processor = - getCanonicalProcessorName(T, OptionalProcessor.getValue()); + llvm::StringRef Processor = getCanonicalProcessorName(T, *OptionalProcessor); if (Processor.empty()) - return llvm::None; + return std::nullopt; llvm::SmallSet<llvm::StringRef, 4> AllFeatures; for (auto &&F : getAllPossibleTargetIDFeatures(T, Processor)) @@ -120,7 +120,7 @@ parseTargetID(const llvm::Triple &T, llvm::StringRef TargetID, for (auto &&F : *FeatureMap) if (!AllFeatures.count(F.first())) - return llvm::None; + return std::nullopt; return Processor; } @@ -133,7 +133,7 @@ std::string getCanonicalTargetID(llvm::StringRef Processor, std::map<const llvm::StringRef, bool> OrderedMap; for (const auto &F : Features) OrderedMap[F.first()] = F.second; - for (auto F : OrderedMap) + for (const auto &F : OrderedMap) TargetID = TargetID + ':' + F.first.str() + (F.second ? "+" : "-"); return TargetID; } @@ -141,7 +141,7 @@ std::string getCanonicalTargetID(llvm::StringRef Processor, // For a specific processor, a feature either shows up in all target IDs, or // does not show up in any target IDs. Otherwise the target ID combination // is invalid. -llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>> +std::optional<std::pair<llvm::StringRef, llvm::StringRef>> getConflictTargetIDCombination(const std::set<llvm::StringRef> &TargetIDs) { struct Info { llvm::StringRef TargetID; @@ -150,8 +150,7 @@ getConflictTargetIDCombination(const std::set<llvm::StringRef> &TargetIDs) { llvm::StringMap<Info> FeatureMap; for (auto &&ID : TargetIDs) { llvm::StringMap<bool> Features; - llvm::StringRef Proc = - parseTargetIDWithFormatCheckingOnly(ID, &Features).getValue(); + llvm::StringRef Proc = *parseTargetIDWithFormatCheckingOnly(ID, &Features); auto Loc = FeatureMap.find(Proc); if (Loc == FeatureMap.end()) FeatureMap[Proc] = Info{ID, Features}; @@ -163,7 +162,28 @@ getConflictTargetIDCombination(const std::set<llvm::StringRef> &TargetIDs) { return std::make_pair(Loc->second.TargetID, ID); } } - return llvm::None; + return std::nullopt; +} + +bool isCompatibleTargetID(llvm::StringRef Provided, llvm::StringRef Requested) { + llvm::StringMap<bool> ProvidedFeatures, RequestedFeatures; + llvm::StringRef ProvidedProc = + *parseTargetIDWithFormatCheckingOnly(Provided, &ProvidedFeatures); + llvm::StringRef RequestedProc = + *parseTargetIDWithFormatCheckingOnly(Requested, &RequestedFeatures); + if (ProvidedProc != RequestedProc) + return false; + for (const auto &F : ProvidedFeatures) { + auto Loc = RequestedFeatures.find(F.first()); + // The default (unspecified) value of a feature is 'All', which can match + // either 'On' or 'Off'. + if (Loc == RequestedFeatures.end()) + return false; + // If a feature is specified, it must have exact match. + if (Loc->second != F.second) + return false; + } + return true; } } // namespace clang diff --git a/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp index 5f8e04c2bd6c..96b3ad9ba2f2 100644 --- a/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp +++ b/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements the TargetInfo and TargetInfoImpl interfaces. +// This file implements the TargetInfo interface. // //===----------------------------------------------------------------------===// @@ -14,18 +14,44 @@ #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticFrontend.h" #include "clang/Basic/LangOptions.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/TargetParser.h" +#include "llvm/TargetParser/TargetParser.h" #include <cstdlib> using namespace clang; static const LangASMap DefaultAddrSpaceMap = {0}; +// The fake address space map must have a distinct entry for each +// language-specific address space. +static const LangASMap FakeAddrSpaceMap = { + 0, // Default + 1, // opencl_global + 3, // opencl_local + 2, // opencl_constant + 0, // opencl_private + 4, // opencl_generic + 5, // opencl_global_device + 6, // opencl_global_host + 7, // cuda_device + 8, // cuda_constant + 9, // cuda_shared + 1, // sycl_global + 5, // sycl_global_device + 6, // sycl_global_host + 3, // sycl_local + 0, // sycl_private + 10, // ptr32_sptr + 11, // ptr32_uptr + 12, // ptr64 + 13, // hlsl_groupshared + 20, // wasm_funcref +}; // TargetInfo Constructor. -TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { +TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or // SPARC. These should be overridden by concrete targets as needed. BigEndian = !T.isLittleEndian(); @@ -33,15 +59,21 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { VLASupported = true; NoAsmVariants = false; HasLegalHalfType = false; + HalfArgsAndReturns = false; HasFloat128 = false; + HasIbm128 = false; HasFloat16 = false; HasBFloat16 = false; + HasFullBFloat16 = false; + HasLongDouble = true; + HasFPReturn = true; HasStrictFP = false; PointerWidth = PointerAlign = 32; BoolWidth = BoolAlign = 8; IntWidth = IntAlign = 32; LongWidth = LongAlign = 32; LongLongWidth = LongLongAlign = 64; + Int128Align = 128; // Fixed point default bit widths ShortAccumWidth = ShortAccumAlign = 16; @@ -66,11 +98,12 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { // From the glibc documentation, on GNU systems, malloc guarantees 16-byte // alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html. - // This alignment guarantee also applies to Windows and Android. On Darwin, - // the alignment is 16 bytes on both 64-bit and 32-bit systems. - if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid()) + // This alignment guarantee also applies to Windows and Android. On Darwin + // and OpenBSD, the alignment is 16 bytes on both 64-bit and 32-bit systems. + if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid() || + T.isOHOSFamily()) NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0; - else if (T.isOSDarwin()) + else if (T.isOSDarwin() || T.isOSOpenBSD()) NewAlign = 128; else NewAlign = 0; // Infer from basic type alignment. @@ -83,12 +116,12 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { LongDoubleWidth = 64; LongDoubleAlign = 64; Float128Align = 128; + Ibm128Align = 128; LargeArrayMinWidth = 0; LargeArrayAlign = 0; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; MaxVectorAlign = 0; MaxTLSAlign = 0; - SimdDefaultAlign = 0; SizeType = UnsignedLong; PtrDiffType = SignedLong; IntMaxType = SignedLongLong; @@ -113,6 +146,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { DoubleFormat = &llvm::APFloat::IEEEdouble(); LongDoubleFormat = &llvm::APFloat::IEEEdouble(); Float128Format = &llvm::APFloat::IEEEquad(); + Ibm128Format = &llvm::APFloat::PPCDoubleDouble(); MCountName = "mcount"; UserLabelPrefix = "_"; RegParmMax = 0; @@ -126,7 +160,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { ARMCDECoprocMask = 0; // Default to no types using fpret. - RealTypeUsesObjCFPRet = 0; + RealTypeUsesObjCFPRetMask = 0; // Default to not using fp2ret for __Complex long double ComplexLongDoubleUsesFP2Ret = false; @@ -145,6 +179,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { PlatformMinVersion = VersionTuple(); MaxOpenCLWorkGroupSize = 1024; + + MaxBitIntWidth.reset(); } // Out of line virtual dtor for TargetInfo. @@ -198,11 +234,11 @@ const char *TargetInfo::getTypeConstantSuffix(IntType T) const { case UnsignedChar: if (getCharWidth() < getIntWidth()) return ""; - LLVM_FALLTHROUGH; + [[fallthrough]]; case UnsignedShort: if (getShortWidth() < getIntWidth()) return ""; - LLVM_FALLTHROUGH; + [[fallthrough]]; case UnsignedInt: return "U"; case UnsignedLong: return "UL"; case UnsignedLongLong: return "ULL"; @@ -276,32 +312,38 @@ TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth, return NoInt; } -TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth, - bool ExplicitIEEE) const { +FloatModeKind TargetInfo::getRealTypeByWidth(unsigned BitWidth, + FloatModeKind ExplicitType) const { + if (getHalfWidth() == BitWidth) + return FloatModeKind::Half; if (getFloatWidth() == BitWidth) - return Float; + return FloatModeKind::Float; if (getDoubleWidth() == BitWidth) - return Double; + return FloatModeKind::Double; switch (BitWidth) { case 96: if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended()) - return LongDouble; + return FloatModeKind::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 (ExplicitType == FloatModeKind::Float128) + return hasFloat128Type() ? FloatModeKind::Float128 + : FloatModeKind::NoFloat; + if (ExplicitType == FloatModeKind::Ibm128) + return hasIbm128Type() ? FloatModeKind::Ibm128 + : FloatModeKind::NoFloat; if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() || &getLongDoubleFormat() == &llvm::APFloat::IEEEquad()) - return LongDouble; + return FloatModeKind::LongDouble; if (hasFloat128Type()) - return Float128; + return FloatModeKind::Float128; break; } - return NoFloat; + return FloatModeKind::NoFloat; } /// getTypeAlign - Return the alignment (in bits) of the specified integer type @@ -406,12 +448,14 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { // for OpenCL C 2.0 but with no access to target capabilities. Target // should be immutable once created and thus these language options need // to be defined only once. - if (Opts.OpenCLVersion == 300) { + if (Opts.getOpenCLCompatibleVersion() == 300) { const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts(); Opts.OpenCLGenericAddressSpace = hasFeatureEnabled( OpenCLFeaturesMap, "__opencl_c_generic_address_space"); Opts.OpenCLPipes = hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_pipes"); + Opts.Blocks = + hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_device_enqueue"); } } @@ -437,6 +481,20 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { } else if (Opts.LongDoubleSize == 128) { LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } else if (Opts.LongDoubleSize == 80) { + LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); + if (getTriple().isWindowsMSVCEnvironment()) { + LongDoubleWidth = 128; + LongDoubleAlign = 128; + } else { // Linux + if (getTriple().getArch() == llvm::Triple::x86) { + LongDoubleWidth = 96; + LongDoubleAlign = 32; + } else { + LongDoubleWidth = 128; + LongDoubleAlign = 128; + } + } } } @@ -452,6 +510,12 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { Diags.Report(diag::err_opt_not_valid_on_target) << "-fprotect-parens"; Opts.ProtectParens = false; } + + if (Opts.MaxBitIntWidth) + MaxBitIntWidth = static_cast<unsigned>(Opts.MaxBitIntWidth); + + if (Opts.FakeAddressSpaceMap) + AddrSpaceMap = &FakeAddrSpaceMap; } bool TargetInfo::initFeatureMap( @@ -459,21 +523,73 @@ bool TargetInfo::initFeatureMap( const std::vector<std::string> &FeatureVec) const { for (const auto &F : FeatureVec) { StringRef Name = F; + if (Name.empty()) + continue; // Apply the feature via the target. - bool Enabled = Name[0] == '+'; - setFeatureEnabled(Features, Name.substr(1), Enabled); + if (Name[0] != '+' && Name[0] != '-') + Diags.Report(diag::warn_fe_backend_invalid_feature_flag) << Name; + else + setFeatureEnabled(Features, Name.substr(1), Name[0] == '+'); } return true; } +ParsedTargetAttr TargetInfo::parseTargetAttr(StringRef Features) const { + ParsedTargetAttr Ret; + if (Features == "default") + return Ret; + SmallVector<StringRef, 1> AttrFeatures; + Features.split(AttrFeatures, ","); + + // Grab the various features and prepend a "+" to turn on the feature to + // the backend and add them to our existing set of features. + for (auto &Feature : AttrFeatures) { + // Go ahead and trim whitespace rather than either erroring or + // accepting it weirdly. + Feature = Feature.trim(); + + // TODO: Support the fpmath option. It will require checking + // overall feature validity for the function with the rest of the + // attributes on the function. + if (Feature.starts_with("fpmath=")) + continue; + + if (Feature.starts_with("branch-protection=")) { + Ret.BranchProtection = Feature.split('=').second.trim(); + continue; + } + + // While we're here iterating check for a different target cpu. + if (Feature.starts_with("arch=")) { + if (!Ret.CPU.empty()) + Ret.Duplicate = "arch="; + else + Ret.CPU = Feature.split("=").second.trim(); + } else if (Feature.starts_with("tune=")) { + if (!Ret.Tune.empty()) + Ret.Duplicate = "tune="; + else + Ret.Tune = Feature.split("=").second.trim(); + } else if (Feature.starts_with("no-")) + Ret.Features.push_back("-" + Feature.split("-").second.str()); + else + Ret.Features.push_back("+" + Feature.str()); + } + return Ret; +} + TargetInfo::CallingConvKind TargetInfo::getCallingConvKind(bool ClangABICompat4) const { if (getCXXABI() != TargetCXXABI::Microsoft && - (ClangABICompat4 || getTriple().getOS() == llvm::Triple::PS4)) + (ClangABICompat4 || getTriple().isPS4())) return CCK_ClangABI4OrPS4; return CCK_Default; } +bool TargetInfo::areDefaultedSMFStillPOD(const LangOptions &LangOpts) const { + return LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver15; +} + LangAS TargetInfo::getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const { switch (TK) { case OCLTK_Image: diff --git a/contrib/llvm-project/clang/lib/Basic/Targets.cpp b/contrib/llvm-project/clang/lib/Basic/Targets.cpp index ba91d0439968..e3283510c6aa 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets.cpp @@ -19,9 +19,12 @@ #include "Targets/ARM.h" #include "Targets/AVR.h" #include "Targets/BPF.h" +#include "Targets/CSKY.h" +#include "Targets/DirectX.h" #include "Targets/Hexagon.h" #include "Targets/Lanai.h" #include "Targets/Le64.h" +#include "Targets/LoongArch.h" #include "Targets/M68k.h" #include "Targets/MSP430.h" #include "Targets/Mips.h" @@ -39,8 +42,9 @@ #include "Targets/X86.h" #include "Targets/XCore.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticFrontend.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" using namespace clang; @@ -78,9 +82,10 @@ void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName, bool Tuning) { void addCygMingDefines(const LangOptions &Opts, MacroBuilder &Builder) { // Mingw and cygwin define __declspec(a) to __attribute__((a)). Clang - // supports __declspec natively under -fms-extensions, but we define a no-op - // __declspec macro anyway for pre-processor compatibility. - if (Opts.MicrosoftExt) + // supports __declspec natively under -fdeclspec (also enabled with + // -fms-extensions), but we define a no-op __declspec macro anyway for + // pre-processor compatibility. + if (Opts.DeclSpecKeyword) Builder.defineMacro("__declspec", "__declspec"); else Builder.defineMacro("__declspec(a)", "__attribute__((a))"); @@ -104,8 +109,8 @@ void addCygMingDefines(const LangOptions &Opts, MacroBuilder &Builder) { // Driver code //===----------------------------------------------------------------------===// -TargetInfo *AllocateTarget(const llvm::Triple &Triple, - const TargetOptions &Opts) { +std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, + const TargetOptions &Opts) { llvm::Triple::OSType os = Triple.getOS(); switch (Triple.getArch()) { @@ -113,498 +118,564 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return nullptr; case llvm::Triple::arc: - return new ARCTargetInfo(Triple, Opts); + return std::make_unique<ARCTargetInfo>(Triple, Opts); case llvm::Triple::xcore: - return new XCoreTargetInfo(Triple, Opts); + return std::make_unique<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); + return std::make_unique<LinuxTargetInfo<HexagonTargetInfo>>(Triple, Opts); + return std::make_unique<HexagonTargetInfo>(Triple, Opts); case llvm::Triple::lanai: - return new LanaiTargetInfo(Triple, Opts); + return std::make_unique<LanaiTargetInfo>(Triple, Opts); case llvm::Triple::aarch64_32: if (Triple.isOSDarwin()) - return new DarwinAArch64TargetInfo(Triple, Opts); + return std::make_unique<DarwinAArch64TargetInfo>(Triple, Opts); return nullptr; case llvm::Triple::aarch64: if (Triple.isOSDarwin()) - return new DarwinAArch64TargetInfo(Triple, Opts); + return std::make_unique<DarwinAArch64TargetInfo>(Triple, Opts); switch (os) { - case llvm::Triple::CloudABI: - return new CloudABITargetInfo<AArch64leTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<AArch64leTargetInfo>>(Triple, + Opts); case llvm::Triple::Fuchsia: - return new FuchsiaTargetInfo<AArch64leTargetInfo>(Triple, Opts); + return std::make_unique<FuchsiaTargetInfo<AArch64leTargetInfo>>(Triple, + Opts); + case llvm::Triple::Haiku: + return std::make_unique<HaikuTargetInfo<AArch64leTargetInfo>>(Triple, + Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo<AArch64leTargetInfo>(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return std::make_unique<LinuxTargetInfo<AArch64leTargetInfo>>(Triple, + Opts); + case llvm::Triple::OpenHOS: + return std::make_unique<OHOSTargetInfo<AArch64leTargetInfo>>(Triple, + Opts); + } case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<AArch64leTargetInfo>>(Triple, + Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts); + return std::make_unique<OpenBSDTargetInfo<AArch64leTargetInfo>>(Triple, + Opts); case llvm::Triple::Win32: switch (Triple.getEnvironment()) { case llvm::Triple::GNU: - return new MinGWARM64TargetInfo(Triple, Opts); + return std::make_unique<MinGWARM64TargetInfo>(Triple, Opts); case llvm::Triple::MSVC: default: // Assume MSVC for unknown environments - return new MicrosoftARM64TargetInfo(Triple, Opts); + return std::make_unique<MicrosoftARM64TargetInfo>(Triple, Opts); } default: - return new AArch64leTargetInfo(Triple, Opts); + return std::make_unique<AArch64leTargetInfo>(Triple, Opts); } case llvm::Triple::aarch64_be: switch (os) { case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<AArch64beTargetInfo>>(Triple, + Opts); case llvm::Triple::Fuchsia: - return new FuchsiaTargetInfo<AArch64beTargetInfo>(Triple, Opts); + return std::make_unique<FuchsiaTargetInfo<AArch64beTargetInfo>>(Triple, + Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo<AArch64beTargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<AArch64beTargetInfo>>(Triple, + Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<AArch64beTargetInfo>>(Triple, + Opts); default: - return new AArch64beTargetInfo(Triple, Opts); + return std::make_unique<AArch64beTargetInfo>(Triple, Opts); } case llvm::Triple::arm: case llvm::Triple::thumb: if (Triple.isOSBinFormatMachO()) - return new DarwinARMTargetInfo(Triple, Opts); + return std::make_unique<DarwinARMTargetInfo>(Triple, Opts); switch (os) { - case llvm::Triple::CloudABI: - return new CloudABITargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo<ARMleTargetInfo>(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return std::make_unique<LinuxTargetInfo<ARMleTargetInfo>>(Triple, Opts); + case llvm::Triple::OpenHOS: + return std::make_unique<OHOSTargetInfo<ARMleTargetInfo>>(Triple, Opts); + } + case llvm::Triple::LiteOS: + return std::make_unique<OHOSTargetInfo<ARMleTargetInfo>>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<ARMleTargetInfo>>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<ARMleTargetInfo>>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); + return std::make_unique<OpenBSDTargetInfo<ARMleTargetInfo>>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<ARMleTargetInfo>(Triple, Opts); + return std::make_unique<RTEMSTargetInfo<ARMleTargetInfo>>(Triple, Opts); + case llvm::Triple::Haiku: + return std::make_unique<HaikuTargetInfo<ARMleTargetInfo>>(Triple, Opts); case llvm::Triple::NaCl: - return new NaClTargetInfo<ARMleTargetInfo>(Triple, Opts); + return std::make_unique<NaClTargetInfo<ARMleTargetInfo>>(Triple, Opts); case llvm::Triple::Win32: switch (Triple.getEnvironment()) { case llvm::Triple::Cygnus: - return new CygwinARMTargetInfo(Triple, Opts); + return std::make_unique<CygwinARMTargetInfo>(Triple, Opts); case llvm::Triple::GNU: - return new MinGWARMTargetInfo(Triple, Opts); + return std::make_unique<MinGWARMTargetInfo>(Triple, Opts); case llvm::Triple::Itanium: - return new ItaniumWindowsARMleTargetInfo(Triple, Opts); + return std::make_unique<ItaniumWindowsARMleTargetInfo>(Triple, Opts); case llvm::Triple::MSVC: default: // Assume MSVC for unknown environments - return new MicrosoftARMleTargetInfo(Triple, Opts); + return std::make_unique<MicrosoftARMleTargetInfo>(Triple, Opts); } default: - return new ARMleTargetInfo(Triple, Opts); + return std::make_unique<ARMleTargetInfo>(Triple, Opts); } case llvm::Triple::armeb: case llvm::Triple::thumbeb: if (Triple.isOSDarwin()) - return new DarwinARMTargetInfo(Triple, Opts); + return std::make_unique<DarwinARMTargetInfo>(Triple, Opts); switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<ARMbeTargetInfo>(Triple, Opts); - case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<ARMbeTargetInfo>>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); - case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<ARMbeTargetInfo>>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<ARMbeTargetInfo>(Triple, Opts); + return std::make_unique<RTEMSTargetInfo<ARMbeTargetInfo>>(Triple, Opts); case llvm::Triple::NaCl: - return new NaClTargetInfo<ARMbeTargetInfo>(Triple, Opts); + return std::make_unique<NaClTargetInfo<ARMbeTargetInfo>>(Triple, Opts); default: - return new ARMbeTargetInfo(Triple, Opts); + return std::make_unique<ARMbeTargetInfo>(Triple, Opts); } case llvm::Triple::avr: - return new AVRTargetInfo(Triple, Opts); + return std::make_unique<AVRTargetInfo>(Triple, Opts); case llvm::Triple::bpfeb: case llvm::Triple::bpfel: - return new BPFTargetInfo(Triple, Opts); + return std::make_unique<BPFTargetInfo>(Triple, Opts); case llvm::Triple::msp430: - return new MSP430TargetInfo(Triple, Opts); + return std::make_unique<MSP430TargetInfo>(Triple, Opts); case llvm::Triple::mips: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<RTEMSTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<MipsTargetInfo>>(Triple, Opts); default: - return new MipsTargetInfo(Triple, Opts); + return std::make_unique<MipsTargetInfo>(Triple, Opts); } case llvm::Triple::mipsel: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return std::make_unique<LinuxTargetInfo<MipsTargetInfo>>(Triple, Opts); + case llvm::Triple::OpenHOS: + return std::make_unique<OHOSTargetInfo<MipsTargetInfo>>(Triple, Opts); + } case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<RTEMSTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::NaCl: - return new NaClTargetInfo<NaClMips32TargetInfo>(Triple, Opts); + return std::make_unique<NaClTargetInfo<NaClMips32TargetInfo>>(Triple, + Opts); default: - return new MipsTargetInfo(Triple, Opts); + return std::make_unique<MipsTargetInfo>(Triple, Opts); } case llvm::Triple::mips64: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<RTEMSTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<OpenBSDTargetInfo<MipsTargetInfo>>(Triple, Opts); default: - return new MipsTargetInfo(Triple, Opts); + return std::make_unique<MipsTargetInfo>(Triple, Opts); } case llvm::Triple::mips64el: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<RTEMSTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<MipsTargetInfo>>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts); + return std::make_unique<OpenBSDTargetInfo<MipsTargetInfo>>(Triple, Opts); default: - return new MipsTargetInfo(Triple, Opts); + return std::make_unique<MipsTargetInfo>(Triple, Opts); } case llvm::Triple::m68k: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<M68kTargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<M68kTargetInfo>>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<M68kTargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<M68kTargetInfo>>(Triple, Opts); default: - return new M68kTargetInfo(Triple, Opts); + return std::make_unique<M68kTargetInfo>(Triple, Opts); } case llvm::Triple::le32: switch (os) { case llvm::Triple::NaCl: - return new NaClTargetInfo<PNaClTargetInfo>(Triple, Opts); + return std::make_unique<NaClTargetInfo<PNaClTargetInfo>>(Triple, Opts); default: return nullptr; } case llvm::Triple::le64: - return new Le64TargetInfo(Triple, Opts); + return std::make_unique<Le64TargetInfo>(Triple, Opts); case llvm::Triple::ppc: - if (Triple.isOSDarwin()) - return new DarwinPPC32TargetInfo(Triple, Opts); switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<PPC32TargetInfo>>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<PPC32TargetInfo>>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<PPC32TargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<PPC32TargetInfo>>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple, Opts); + return std::make_unique<OpenBSDTargetInfo<PPC32TargetInfo>>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<PPC32TargetInfo>(Triple, Opts); + return std::make_unique<RTEMSTargetInfo<PPC32TargetInfo>>(Triple, Opts); case llvm::Triple::AIX: - return new AIXPPC32TargetInfo(Triple, Opts); + return std::make_unique<AIXPPC32TargetInfo>(Triple, Opts); default: - return new PPC32TargetInfo(Triple, Opts); + return std::make_unique<PPC32TargetInfo>(Triple, Opts); } case llvm::Triple::ppcle: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<PPC32TargetInfo>>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<PPC32TargetInfo>>(Triple, Opts); default: - return new PPC32TargetInfo(Triple, Opts); + return std::make_unique<PPC32TargetInfo>(Triple, Opts); } case llvm::Triple::ppc64: - if (Triple.isOSDarwin()) - return new DarwinPPC64TargetInfo(Triple, Opts); switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<PPC64TargetInfo>>(Triple, Opts); case llvm::Triple::Lv2: - return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple, Opts); + return std::make_unique<PS3PPUTargetInfo<PPC64TargetInfo>>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<PPC64TargetInfo>>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<PPC64TargetInfo>>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); + return std::make_unique<OpenBSDTargetInfo<PPC64TargetInfo>>(Triple, Opts); case llvm::Triple::AIX: - return new AIXPPC64TargetInfo(Triple, Opts); + return std::make_unique<AIXPPC64TargetInfo>(Triple, Opts); default: - return new PPC64TargetInfo(Triple, Opts); + return std::make_unique<PPC64TargetInfo>(Triple, Opts); } case llvm::Triple::ppc64le: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<PPC64TargetInfo>>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<PPC64TargetInfo>>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<PPC64TargetInfo>>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); + return std::make_unique<OpenBSDTargetInfo<PPC64TargetInfo>>(Triple, Opts); default: - return new PPC64TargetInfo(Triple, Opts); + return std::make_unique<PPC64TargetInfo>(Triple, Opts); } case llvm::Triple::nvptx: - return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/32); + return std::make_unique<NVPTXTargetInfo>(Triple, Opts, + /*TargetPointerWidth=*/32); case llvm::Triple::nvptx64: - return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/64); + return std::make_unique<NVPTXTargetInfo>(Triple, Opts, + /*TargetPointerWidth=*/64); case llvm::Triple::amdgcn: case llvm::Triple::r600: - return new AMDGPUTargetInfo(Triple, Opts); + return std::make_unique<AMDGPUTargetInfo>(Triple, Opts); case llvm::Triple::riscv32: - // TODO: add cases for NetBSD, RTEMS once tested. switch (os) { - case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<RISCV32TargetInfo>(Triple, Opts); + case llvm::Triple::NetBSD: + return std::make_unique<NetBSDTargetInfo<RISCV32TargetInfo>>(Triple, + Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo<RISCV32TargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<RISCV32TargetInfo>>(Triple, Opts); default: - return new RISCV32TargetInfo(Triple, Opts); + return std::make_unique<RISCV32TargetInfo>(Triple, Opts); } case llvm::Triple::riscv64: - // TODO: add cases for NetBSD, RTEMS once tested. switch (os) { case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<RISCV64TargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<RISCV64TargetInfo>>(Triple, + Opts); + case llvm::Triple::NetBSD: + return std::make_unique<NetBSDTargetInfo<RISCV64TargetInfo>>(Triple, + Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<RISCV64TargetInfo>(Triple, Opts); + return std::make_unique<OpenBSDTargetInfo<RISCV64TargetInfo>>(Triple, + Opts); case llvm::Triple::Fuchsia: - return new FuchsiaTargetInfo<RISCV64TargetInfo>(Triple, Opts); + return std::make_unique<FuchsiaTargetInfo<RISCV64TargetInfo>>(Triple, + Opts); + case llvm::Triple::Haiku: + return std::make_unique<HaikuTargetInfo<RISCV64TargetInfo>>(Triple, + Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo<RISCV64TargetInfo>(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return std::make_unique<LinuxTargetInfo<RISCV64TargetInfo>>(Triple, + Opts); + case llvm::Triple::OpenHOS: + return std::make_unique<OHOSTargetInfo<RISCV64TargetInfo>>(Triple, + Opts); + } default: - return new RISCV64TargetInfo(Triple, Opts); + return std::make_unique<RISCV64TargetInfo>(Triple, Opts); } case llvm::Triple::sparc: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<SparcV8TargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<SparcV8TargetInfo>>(Triple, Opts); case llvm::Triple::Solaris: - return new SolarisTargetInfo<SparcV8TargetInfo>(Triple, Opts); + return std::make_unique<SolarisTargetInfo<SparcV8TargetInfo>>(Triple, + Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<SparcV8TargetInfo>>(Triple, + Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple, Opts); + return std::make_unique<RTEMSTargetInfo<SparcV8TargetInfo>>(Triple, Opts); default: - return new SparcV8TargetInfo(Triple, Opts); + return std::make_unique<SparcV8TargetInfo>(Triple, Opts); } - // The 'sparcel' architecture copies all the above cases except for Solaris. case llvm::Triple::sparcel: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<SparcV8elTargetInfo>(Triple, Opts); - case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<SparcV8elTargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<SparcV8elTargetInfo>>(Triple, + Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<SparcV8elTargetInfo>(Triple, Opts); + return std::make_unique<RTEMSTargetInfo<SparcV8elTargetInfo>>(Triple, + Opts); default: - return new SparcV8elTargetInfo(Triple, Opts); + return std::make_unique<SparcV8elTargetInfo>(Triple, Opts); } case llvm::Triple::sparcv9: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<SparcV9TargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<SparcV9TargetInfo>>(Triple, Opts); case llvm::Triple::Solaris: - return new SolarisTargetInfo<SparcV9TargetInfo>(Triple, Opts); + return std::make_unique<SolarisTargetInfo<SparcV9TargetInfo>>(Triple, + Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<SparcV9TargetInfo>>(Triple, + Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts); + return std::make_unique<OpenBSDTargetInfo<SparcV9TargetInfo>>(Triple, + Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<SparcV9TargetInfo>>(Triple, + Opts); default: - return new SparcV9TargetInfo(Triple, Opts); + return std::make_unique<SparcV9TargetInfo>(Triple, Opts); } case llvm::Triple::systemz: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<SystemZTargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<SystemZTargetInfo>>(Triple, Opts); case llvm::Triple::ZOS: - return new ZOSTargetInfo<SystemZTargetInfo>(Triple, Opts); + return std::make_unique<ZOSTargetInfo<SystemZTargetInfo>>(Triple, Opts); default: - return new SystemZTargetInfo(Triple, Opts); + return std::make_unique<SystemZTargetInfo>(Triple, Opts); } case llvm::Triple::tce: - return new TCETargetInfo(Triple, Opts); + return std::make_unique<TCETargetInfo>(Triple, Opts); case llvm::Triple::tcele: - return new TCELETargetInfo(Triple, Opts); + return std::make_unique<TCELETargetInfo>(Triple, Opts); case llvm::Triple::x86: if (Triple.isOSDarwin()) - return new DarwinI386TargetInfo(Triple, Opts); + return std::make_unique<DarwinI386TargetInfo>(Triple, Opts); switch (os) { - case llvm::Triple::Ananas: - return new AnanasTargetInfo<X86_32TargetInfo>(Triple, Opts); - case llvm::Triple::CloudABI: - return new CloudABITargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::Linux: { switch (Triple.getEnvironment()) { default: - return new LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<X86_32TargetInfo>>(Triple, + Opts); case llvm::Triple::Android: - return new AndroidX86_32TargetInfo(Triple, Opts); + return std::make_unique<AndroidX86_32TargetInfo>(Triple, Opts); } } case llvm::Triple::DragonFly: - return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); + return std::make_unique<DragonFlyBSDTargetInfo<X86_32TargetInfo>>(Triple, + Opts); case llvm::Triple::NetBSD: - return new NetBSDI386TargetInfo(Triple, Opts); + return std::make_unique<NetBSDI386TargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDI386TargetInfo(Triple, Opts); + return std::make_unique<OpenBSDI386TargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<X86_32TargetInfo>>(Triple, + Opts); case llvm::Triple::Fuchsia: - return new FuchsiaTargetInfo<X86_32TargetInfo>(Triple, Opts); + return std::make_unique<FuchsiaTargetInfo<X86_32TargetInfo>>(Triple, + Opts); case llvm::Triple::KFreeBSD: - return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); - case llvm::Triple::Minix: - return new MinixTargetInfo<X86_32TargetInfo>(Triple, Opts); + return std::make_unique<KFreeBSDTargetInfo<X86_32TargetInfo>>(Triple, + Opts); case llvm::Triple::Solaris: - return new SolarisTargetInfo<X86_32TargetInfo>(Triple, Opts); + return std::make_unique<SolarisTargetInfo<X86_32TargetInfo>>(Triple, + Opts); case llvm::Triple::Win32: { switch (Triple.getEnvironment()) { case llvm::Triple::Cygnus: - return new CygwinX86_32TargetInfo(Triple, Opts); + return std::make_unique<CygwinX86_32TargetInfo>(Triple, Opts); case llvm::Triple::GNU: - return new MinGWX86_32TargetInfo(Triple, Opts); + return std::make_unique<MinGWX86_32TargetInfo>(Triple, Opts); case llvm::Triple::Itanium: case llvm::Triple::MSVC: default: // Assume MSVC for unknown environments - return new MicrosoftX86_32TargetInfo(Triple, Opts); + return std::make_unique<MicrosoftX86_32TargetInfo>(Triple, Opts); } } case llvm::Triple::Haiku: - return new HaikuX86_32TargetInfo(Triple, Opts); + return std::make_unique<HaikuX86_32TargetInfo>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSX86_32TargetInfo(Triple, Opts); + return std::make_unique<RTEMSX86_32TargetInfo>(Triple, Opts); case llvm::Triple::NaCl: - return new NaClTargetInfo<X86_32TargetInfo>(Triple, Opts); + return std::make_unique<NaClTargetInfo<X86_32TargetInfo>>(Triple, Opts); case llvm::Triple::ELFIAMCU: - return new MCUX86_32TargetInfo(Triple, Opts); + return std::make_unique<MCUX86_32TargetInfo>(Triple, Opts); case llvm::Triple::Hurd: - return new HurdTargetInfo<X86_32TargetInfo>(Triple, Opts); + return std::make_unique<HurdTargetInfo<X86_32TargetInfo>>(Triple, Opts); default: - return new X86_32TargetInfo(Triple, Opts); + return std::make_unique<X86_32TargetInfo>(Triple, Opts); } case llvm::Triple::x86_64: if (Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) - return new DarwinX86_64TargetInfo(Triple, Opts); + return std::make_unique<DarwinX86_64TargetInfo>(Triple, Opts); switch (os) { - case llvm::Triple::Ananas: - return new AnanasTargetInfo<X86_64TargetInfo>(Triple, Opts); - case llvm::Triple::CloudABI: - return new CloudABITargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::Linux: { switch (Triple.getEnvironment()) { default: - return new LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<X86_64TargetInfo>>(Triple, + Opts); case llvm::Triple::Android: - return new AndroidX86_64TargetInfo(Triple, Opts); + return std::make_unique<AndroidX86_64TargetInfo>(Triple, Opts); + case llvm::Triple::OpenHOS: + return std::make_unique<OHOSX86_64TargetInfo>(Triple, Opts); } } case llvm::Triple::DragonFly: - return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); + return std::make_unique<DragonFlyBSDTargetInfo<X86_64TargetInfo>>(Triple, + Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); + return std::make_unique<NetBSDTargetInfo<X86_64TargetInfo>>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDX86_64TargetInfo(Triple, Opts); + return std::make_unique<OpenBSDX86_64TargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); + return std::make_unique<FreeBSDTargetInfo<X86_64TargetInfo>>(Triple, + Opts); case llvm::Triple::Fuchsia: - return new FuchsiaTargetInfo<X86_64TargetInfo>(Triple, Opts); + return std::make_unique<FuchsiaTargetInfo<X86_64TargetInfo>>(Triple, + Opts); case llvm::Triple::KFreeBSD: - return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); + return std::make_unique<KFreeBSDTargetInfo<X86_64TargetInfo>>(Triple, + Opts); case llvm::Triple::Solaris: - return new SolarisTargetInfo<X86_64TargetInfo>(Triple, Opts); + return std::make_unique<SolarisTargetInfo<X86_64TargetInfo>>(Triple, + Opts); case llvm::Triple::Win32: { switch (Triple.getEnvironment()) { case llvm::Triple::Cygnus: - return new CygwinX86_64TargetInfo(Triple, Opts); + return std::make_unique<CygwinX86_64TargetInfo>(Triple, Opts); case llvm::Triple::GNU: - return new MinGWX86_64TargetInfo(Triple, Opts); + return std::make_unique<MinGWX86_64TargetInfo>(Triple, Opts); case llvm::Triple::MSVC: default: // Assume MSVC for unknown environments - return new MicrosoftX86_64TargetInfo(Triple, Opts); + return std::make_unique<MicrosoftX86_64TargetInfo>(Triple, Opts); } } case llvm::Triple::Haiku: - return new HaikuTargetInfo<X86_64TargetInfo>(Triple, Opts); + return std::make_unique<HaikuTargetInfo<X86_64TargetInfo>>(Triple, Opts); case llvm::Triple::NaCl: - return new NaClTargetInfo<X86_64TargetInfo>(Triple, Opts); + return std::make_unique<NaClTargetInfo<X86_64TargetInfo>>(Triple, Opts); case llvm::Triple::PS4: - return new PS4OSTargetInfo<X86_64TargetInfo>(Triple, Opts); + return std::make_unique<PS4OSTargetInfo<X86_64TargetInfo>>(Triple, Opts); + case llvm::Triple::PS5: + return std::make_unique<PS5OSTargetInfo<X86_64TargetInfo>>(Triple, Opts); + case llvm::Triple::Hurd: + return std::make_unique<HurdTargetInfo<X86_64TargetInfo>>(Triple, Opts); default: - return new X86_64TargetInfo(Triple, Opts); + return std::make_unique<X86_64TargetInfo>(Triple, Opts); } case llvm::Triple::spir: { if (os != llvm::Triple::UnknownOS || Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) return nullptr; - return new SPIR32TargetInfo(Triple, Opts); + return std::make_unique<SPIR32TargetInfo>(Triple, Opts); } case llvm::Triple::spir64: { if (os != llvm::Triple::UnknownOS || Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) return nullptr; - return new SPIR64TargetInfo(Triple, Opts); + return std::make_unique<SPIR64TargetInfo>(Triple, Opts); + } + case llvm::Triple::spirv: { + return std::make_unique<SPIRVTargetInfo>(Triple, Opts); + } + case llvm::Triple::spirv32: { + if (os != llvm::Triple::UnknownOS || + Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) + return nullptr; + return std::make_unique<SPIRV32TargetInfo>(Triple, Opts); + } + case llvm::Triple::spirv64: { + if (os != llvm::Triple::UnknownOS || + Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) + return nullptr; + return std::make_unique<SPIRV64TargetInfo>(Triple, Opts); } case llvm::Triple::wasm32: if (Triple.getSubArch() != llvm::Triple::NoSubArch || @@ -613,11 +684,14 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return nullptr; switch (os) { case llvm::Triple::WASI: - return new WASITargetInfo<WebAssembly32TargetInfo>(Triple, Opts); + return std::make_unique<WASITargetInfo<WebAssembly32TargetInfo>>(Triple, + Opts); case llvm::Triple::Emscripten: - return new EmscriptenTargetInfo<WebAssembly32TargetInfo>(Triple, Opts); + return std::make_unique<EmscriptenTargetInfo<WebAssembly32TargetInfo>>( + Triple, Opts); case llvm::Triple::UnknownOS: - return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts); + return std::make_unique<WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>>( + Triple, Opts); default: return nullptr; } @@ -628,22 +702,53 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return nullptr; switch (os) { case llvm::Triple::WASI: - return new WASITargetInfo<WebAssembly64TargetInfo>(Triple, Opts); + return std::make_unique<WASITargetInfo<WebAssembly64TargetInfo>>(Triple, + Opts); case llvm::Triple::Emscripten: - return new EmscriptenTargetInfo<WebAssembly64TargetInfo>(Triple, Opts); + return std::make_unique<EmscriptenTargetInfo<WebAssembly64TargetInfo>>( + Triple, Opts); case llvm::Triple::UnknownOS: - return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts); + return std::make_unique<WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>>( + Triple, Opts); default: return nullptr; } + case llvm::Triple::dxil: + return std::make_unique<DirectXTargetInfo>(Triple, Opts); case llvm::Triple::renderscript32: - return new LinuxTargetInfo<RenderScript32TargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<RenderScript32TargetInfo>>(Triple, + Opts); case llvm::Triple::renderscript64: - return new LinuxTargetInfo<RenderScript64TargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<RenderScript64TargetInfo>>(Triple, + Opts); case llvm::Triple::ve: - return new LinuxTargetInfo<VETargetInfo>(Triple, Opts); + return std::make_unique<LinuxTargetInfo<VETargetInfo>>(Triple, Opts); + + case llvm::Triple::csky: + switch (os) { + case llvm::Triple::Linux: + return std::make_unique<LinuxTargetInfo<CSKYTargetInfo>>(Triple, Opts); + default: + return std::make_unique<CSKYTargetInfo>(Triple, Opts); + } + case llvm::Triple::loongarch32: + switch (os) { + case llvm::Triple::Linux: + return std::make_unique<LinuxTargetInfo<LoongArch32TargetInfo>>(Triple, + Opts); + default: + return std::make_unique<LoongArch32TargetInfo>(Triple, Opts); + } + case llvm::Triple::loongarch64: + switch (os) { + case llvm::Triple::Linux: + return std::make_unique<LinuxTargetInfo<LoongArch64TargetInfo>>(Triple, + Opts); + default: + return std::make_unique<LoongArch64TargetInfo>(Triple, Opts); + } } } } // namespace targets @@ -658,7 +763,7 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, llvm::Triple Triple(Opts->Triple); // Construct the target - std::unique_ptr<TargetInfo> Target(AllocateTarget(Triple, *Opts)); + std::unique_ptr<TargetInfo> Target = AllocateTarget(Triple, *Opts); if (!Target) { Diags.Report(diag::err_target_unknown_triple) << Triple.str(); return nullptr; @@ -700,6 +805,13 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, // Compute the default target features, we need the target to handle this // because features may have dependencies on one another. + llvm::erase_if(Opts->FeaturesAsWritten, [&](StringRef Name) { + if (Target->isReadOnlyFeature(Name.substr(1))) { + Diags.Report(diag::warn_fe_backend_readonly_feature_flag) << Name; + return true; + } + return false; + }); if (!Target->initFeatureMap(Opts->FeatureMap, Diags, Opts->CPU, Opts->FeaturesAsWritten)) return nullptr; @@ -719,6 +831,10 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, Target->setCommandLineOpenCLOpts(); Target->setMaxAtomicWidth(); + if (!Opts->DarwinTargetVariantTriple.empty()) + Target->DarwinTargetVariantTriple = + llvm::Triple(Opts->DarwinTargetVariantTriple); + if (!Target->validateTarget(Diags)) return nullptr; @@ -745,7 +861,7 @@ bool TargetInfo::validateOpenCLTarget(const LangOptions &Opts, // Validate that feature macros are set properly for OpenCL C 3.0. // In other cases assume that target is always valid. - if (Opts.OpenCLCPlusPlus || Opts.OpenCLVersion < 300) + if (Opts.getOpenCLCompatibleVersion() < 300) return true; return OpenCLOptions::diagnoseUnsupportedFeatureDependencies(*this, Diags) && diff --git a/contrib/llvm-project/clang/lib/Basic/Targets.h b/contrib/llvm-project/clang/lib/Basic/Targets.h index a063204e69e6..b4d2486b5d2b 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets.h @@ -24,8 +24,8 @@ namespace clang { namespace targets { LLVM_LIBRARY_VISIBILITY -clang::TargetInfo *AllocateTarget(const llvm::Triple &Triple, - const clang::TargetOptions &Opts); +std::unique_ptr<clang::TargetInfo> +AllocateTarget(const llvm::Triple &Triple, const clang::TargetOptions &Opts); /// DefineStd - Define a macro name and standard variants. For example if /// MacroName is "unix", then this will define "__unix", "__unix__", and "unix" diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp index e163ebfa2348..f5a5d689fa09 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp @@ -17,29 +17,116 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/AArch64TargetParser.h" +#include "llvm/TargetParser/AArch64TargetParser.h" +#include "llvm/TargetParser/ARMTargetParserCommon.h" +#include <optional> using namespace clang; using namespace clang::targets; -const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { +static constexpr Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsNEON.def" #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsSVE.def" #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#include "clang/Basic/BuiltinsSME.def" + +#define BUILTIN(ID, TYPE, ATTRS) \ + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ - {#ID, TYPE, ATTRS, nullptr, LANG, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG}, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ - {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, #include "clang/Basic/BuiltinsAArch64.def" }; +void AArch64TargetInfo::setArchFeatures() { + if (*ArchInfo == llvm::AArch64::ARMV8R) { + HasDotProd = true; + HasDIT = true; + HasFlagM = true; + HasRCPC = true; + FPU |= NeonMode; + HasCCPP = true; + HasCRC = true; + HasLSE = true; + HasRDM = true; + } else if (ArchInfo->Version.getMajor() == 8) { + if (ArchInfo->Version.getMinor() >= 7u) { + HasWFxT = true; + } + if (ArchInfo->Version.getMinor() >= 6u) { + HasBFloat16 = true; + HasMatMul = true; + } + if (ArchInfo->Version.getMinor() >= 5u) { + HasAlternativeNZCV = true; + HasFRInt3264 = true; + HasSSBS = true; + HasSB = true; + HasPredRes = true; + HasBTI = true; + } + if (ArchInfo->Version.getMinor() >= 4u) { + HasDotProd = true; + HasDIT = true; + HasFlagM = true; + } + if (ArchInfo->Version.getMinor() >= 3u) { + HasRCPC = true; + FPU |= NeonMode; + } + if (ArchInfo->Version.getMinor() >= 2u) { + HasCCPP = true; + } + if (ArchInfo->Version.getMinor() >= 1u) { + HasCRC = true; + HasLSE = true; + HasRDM = true; + } + } else if (ArchInfo->Version.getMajor() == 9) { + if (ArchInfo->Version.getMinor() >= 2u) { + HasWFxT = true; + } + if (ArchInfo->Version.getMinor() >= 1u) { + HasBFloat16 = true; + HasMatMul = true; + } + FPU |= SveMode; + HasSVE2 = true; + HasFullFP16 = true; + HasAlternativeNZCV = true; + HasFRInt3264 = true; + HasSSBS = true; + HasSB = true; + HasPredRes = true; + HasBTI = true; + HasDotProd = true; + HasDIT = true; + HasFlagM = true; + HasRCPC = true; + FPU |= NeonMode; + HasCCPP = true; + HasCRC = true; + HasLSE = true; + HasRDM = true; + } +} + AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple), ABI("aapcs") { @@ -56,7 +143,9 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, // All AArch64 implementations support ARMv8 FP, which makes half a legal type. HasLegalHalfType = true; + HalfArgsAndReturns = true; HasFloat16 = true; + HasStrictFP = true; if (Triple.isArch64Bit()) LongWidth = LongAlign = PointerWidth = PointerAlign = 64; @@ -117,11 +206,11 @@ bool AArch64TargetInfo::setABI(const std::string &Name) { return true; } -bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, +bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef, BranchProtectionInfo &BPI, StringRef &Err) const { - llvm::AArch64::ParsedBranchProtection PBP; - if (!llvm::AArch64::parseBranchProtection(Spec, PBP, Err)) + llvm::ARM::ParsedBranchProtection PBP; + if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err)) return false; BPI.SignReturnAddr = @@ -136,12 +225,13 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey; BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; + BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR; + BPI.GuardedControlStack = PBP.GuardedControlStack; return true; } bool AArch64TargetInfo::isValidCPUName(StringRef Name) const { - return Name == "generic" || - llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID; + return Name == "generic" || llvm::AArch64::parseCpu(Name); } bool AArch64TargetInfo::setCPU(const std::string &Name) { @@ -156,8 +246,6 @@ void AArch64TargetInfo::fillValidCPUList( void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); - Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1"); - Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); } void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts, @@ -183,6 +271,7 @@ void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts, void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__ARM_FEATURE_FRINT", "1"); + Builder.defineMacro("__ARM_FEATURE_BTI", "1"); // Also include the Armv8.4 defines getTargetDefinesARMV84A(Opts, Builder); } @@ -203,21 +292,72 @@ void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts, getTargetDefinesARMV86A(Opts, Builder); } +void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts, + MacroBuilder &Builder) const { + // Also include the Armv8.7 defines + getTargetDefinesARMV87A(Opts, Builder); +} + +void AArch64TargetInfo::getTargetDefinesARMV89A(const LangOptions &Opts, + MacroBuilder &Builder) const { + // Also include the Armv8.8 defines + getTargetDefinesARMV88A(Opts, Builder); +} + +void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts, + MacroBuilder &Builder) const { + // Armv9-A maps to Armv8.5-A + getTargetDefinesARMV85A(Opts, Builder); +} + +void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts, + MacroBuilder &Builder) const { + // Armv9.1-A maps to Armv8.6-A + getTargetDefinesARMV86A(Opts, Builder); +} + +void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts, + MacroBuilder &Builder) const { + // Armv9.2-A maps to Armv8.7-A + getTargetDefinesARMV87A(Opts, Builder); +} + +void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts, + MacroBuilder &Builder) const { + // Armv9.3-A maps to Armv8.8-A + getTargetDefinesARMV88A(Opts, Builder); +} + +void AArch64TargetInfo::getTargetDefinesARMV94A(const LangOptions &Opts, + MacroBuilder &Builder) const { + // Armv9.4-A maps to Armv8.9-A + getTargetDefinesARMV89A(Opts, Builder); +} + +void AArch64TargetInfo::getTargetDefinesARMV95A(const LangOptions &Opts, + MacroBuilder &Builder) const { + // Armv9.5-A does not have a v8.* equivalent, but is a superset of v9.4-A. + getTargetDefinesARMV94A(Opts, Builder); +} + void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { // Target identification. - Builder.defineMacro("__aarch64__"); - // For bare-metal. - if (getTriple().getOS() == llvm::Triple::UnknownOS && - getTriple().isOSBinFormatELF()) - Builder.defineMacro("__ELF__"); - - // Target properties. - if (!getTriple().isOSWindows() && getTriple().isArch64Bit()) { - Builder.defineMacro("_LP64"); - Builder.defineMacro("__LP64__"); + if (getTriple().isWindowsArm64EC()) { + // Define the same set of macros as would be defined on x86_64 to ensure that + // ARM64EC datatype layouts match those of x86_64 compiled code + Builder.defineMacro("__amd64__"); + Builder.defineMacro("__amd64"); + Builder.defineMacro("__x86_64"); + Builder.defineMacro("__x86_64__"); + Builder.defineMacro("__arm64ec__"); + } else { + Builder.defineMacro("__aarch64__"); } + // Inline assembly supports AArch64 flag outputs. + Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__"); + std::string CodeModel = getTargetOpts().CodeModel; if (CodeModel == "default") CodeModel = "small"; @@ -227,8 +367,10 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, // ACLE predefines. Many can only have one possible value on v8 AArch64. Builder.defineMacro("__ARM_ACLE", "200"); - Builder.defineMacro("__ARM_ARCH", "8"); - Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'"); + Builder.defineMacro("__ARM_ARCH", + std::to_string(ArchInfo->Version.getMajor())); + Builder.defineMacro("__ARM_ARCH_PROFILE", + std::string("'") + (char)ArchInfo->Profile + "'"); Builder.defineMacro("__ARM_64BIT_STATE", "1"); Builder.defineMacro("__ARM_PCS_AAPCS64", "1"); @@ -244,8 +386,14 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4"); + // These macros are set when Clang can parse declarations with these + // attributes. + Builder.defineMacro("__ARM_STATE_ZA", "1"); + Builder.defineMacro("__ARM_STATE_ZT0", "1"); + // 0xe implies support for half, single and double precision operations. - Builder.defineMacro("__ARM_FP", "0xE"); + if (FPU & FPUMode) + Builder.defineMacro("__ARM_FP", "0xE"); // PCS specifies this for SysV variants, which is all we support. Other ABIs // may choose __ARM_FP16_FORMAT_ALTERNATIVE. @@ -269,6 +417,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if (FPU & SveMode) Builder.defineMacro("__ARM_FEATURE_SVE", "1"); + if ((FPU & NeonMode) && (FPU & SveMode)) + Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1"); + if (HasSVE2) Builder.defineMacro("__ARM_FEATURE_SVE2", "1"); @@ -284,9 +435,28 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasSVE2 && HasSVE2SM4) Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1"); + if (HasSME) { + Builder.defineMacro("__ARM_FEATURE_SME"); + Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1"); + } + + if (HasSME2) { + Builder.defineMacro("__ARM_FEATURE_SME"); + Builder.defineMacro("__ARM_FEATURE_SME2"); + Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1"); + } + if (HasCRC) Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); + if (HasRCPC3) + Builder.defineMacro("__ARM_FEATURE_RCPC", "3"); + else if (HasRCPC) + Builder.defineMacro("__ARM_FEATURE_RCPC", "1"); + + if (HasFMV) + Builder.defineMacro("__HAVE_FUNCTION_MULTI_VERSIONING", "1"); + // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature // macros for AES, SHA2, SHA3 and SM4 if (HasAES && HasSHA2) @@ -308,6 +478,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__ARM_FEATURE_SM4", "1"); } + if (HasPAuth) + Builder.defineMacro("__ARM_FEATURE_PAUTH", "1"); + if (HasUnaligned) Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); @@ -375,178 +548,416 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if (Opts.BranchTargetEnforcement) Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1"); + if (Opts.GuardedControlStack) + Builder.defineMacro("__ARM_FEATURE_GCS_DEFAULT", "1"); + if (HasLS64) Builder.defineMacro("__ARM_FEATURE_LS64", "1"); if (HasRandGen) Builder.defineMacro("__ARM_FEATURE_RNG", "1"); - switch (ArchKind) { - default: - break; - case llvm::AArch64::ArchKind::ARMV8_1A: + if (HasMOPS) + Builder.defineMacro("__ARM_FEATURE_MOPS", "1"); + + if (HasD128) + Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1"); + + if (HasGCS) + Builder.defineMacro("__ARM_FEATURE_GCS", "1"); + + if (*ArchInfo == llvm::AArch64::ARMV8_1A) getTargetDefinesARMV81A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_2A: + else if (*ArchInfo == llvm::AArch64::ARMV8_2A) getTargetDefinesARMV82A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_3A: + else if (*ArchInfo == llvm::AArch64::ARMV8_3A) getTargetDefinesARMV83A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_4A: + else if (*ArchInfo == llvm::AArch64::ARMV8_4A) getTargetDefinesARMV84A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_5A: + else if (*ArchInfo == llvm::AArch64::ARMV8_5A) getTargetDefinesARMV85A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_6A: + else if (*ArchInfo == llvm::AArch64::ARMV8_6A) getTargetDefinesARMV86A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_7A: + else if (*ArchInfo == llvm::AArch64::ARMV8_7A) getTargetDefinesARMV87A(Opts, Builder); - break; - } - - // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work. + else if (*ArchInfo == llvm::AArch64::ARMV8_8A) + getTargetDefinesARMV88A(Opts, Builder); + else if (*ArchInfo == llvm::AArch64::ARMV8_9A) + getTargetDefinesARMV89A(Opts, Builder); + else if (*ArchInfo == llvm::AArch64::ARMV9A) + getTargetDefinesARMV9A(Opts, Builder); + else if (*ArchInfo == llvm::AArch64::ARMV9_1A) + getTargetDefinesARMV91A(Opts, Builder); + else if (*ArchInfo == llvm::AArch64::ARMV9_2A) + getTargetDefinesARMV92A(Opts, Builder); + else if (*ArchInfo == llvm::AArch64::ARMV9_3A) + getTargetDefinesARMV93A(Opts, Builder); + else if (*ArchInfo == llvm::AArch64::ARMV9_4A) + getTargetDefinesARMV94A(Opts, Builder); + else if (*ArchInfo == llvm::AArch64::ARMV9_5A) + getTargetDefinesARMV95A(Opts, Builder); + + // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8|16) builtins work. 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"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16"); + + // Allow detection of fast FMA support. + Builder.defineMacro("__FP_FAST_FMA", "1"); + Builder.defineMacro("__FP_FAST_FMAF", "1"); + + // C/C++ operators work on both VLS and VLA SVE types + if (FPU & SveMode) + Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS", "2"); - if (Opts.ArmSveVectorBits) { - Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.ArmSveVectorBits)); - Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS"); + if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) { + Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128)); } } ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin - - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin - + Builtin::FirstTSBuiltin); +} + +std::optional<std::pair<unsigned, unsigned>> +AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const { + if (LangOpts.VScaleMin || LangOpts.VScaleMax) + return std::pair<unsigned, unsigned>( + LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax); + + if (hasFeature("sve")) + return std::pair<unsigned, unsigned>(1, 16); + + return std::nullopt; +} + +unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const { + if (Name == "default") + return 0; + if (auto Ext = llvm::AArch64::parseArchExtension(Name)) + return Ext->FmvPriority; + return 0; +} + +unsigned AArch64TargetInfo::multiVersionFeatureCost() const { + // Take the maximum priority as per feature cost, so more features win. + return llvm::AArch64::ExtensionInfo::MaxFMVPriority; +} + +bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const { + if (auto Ext = llvm::AArch64::parseArchExtension(Name)) + return !Ext->DependentFeatures.empty(); + return false; +} + +StringRef AArch64TargetInfo::getFeatureDependencies(StringRef Name) const { + if (auto Ext = llvm::AArch64::parseArchExtension(Name)) + return Ext->DependentFeatures; + return StringRef(); +} + +bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const { + return llvm::AArch64::parseArchExtension(FeatureStr).has_value(); } bool AArch64TargetInfo::hasFeature(StringRef Feature) const { - return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" || - (Feature == "neon" && (FPU & NeonMode)) || - ((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)) || - (Feature == "ls64" && HasLS64); + return llvm::StringSwitch<bool>(Feature) + .Cases("aarch64", "arm64", "arm", true) + .Case("fmv", HasFMV) + .Cases("neon", "fp", "simd", FPU & NeonMode) + .Case("jscvt", HasJSCVT) + .Case("fcma", HasFCMA) + .Case("rng", HasRandGen) + .Case("flagm", HasFlagM) + .Case("flagm2", HasAlternativeNZCV) + .Case("fp16fml", HasFP16FML) + .Case("dotprod", HasDotProd) + .Case("sm4", HasSM4) + .Case("rdm", HasRDM) + .Case("lse", HasLSE) + .Case("crc", HasCRC) + .Case("sha2", HasSHA2) + .Case("sha3", HasSHA3) + .Cases("aes", "pmull", HasAES) + .Cases("fp16", "fullfp16", HasFullFP16) + .Case("dit", HasDIT) + .Case("dpb", HasCCPP) + .Case("dpb2", HasCCDP) + .Case("rcpc", HasRCPC) + .Case("frintts", HasFRInt3264) + .Case("i8mm", HasMatMul) + .Case("bf16", HasBFloat16) + .Case("sve", FPU & SveMode) + .Case("sve-bf16", FPU & SveMode && HasBFloat16) + .Case("sve-i8mm", FPU & SveMode && HasMatMul) + .Case("f32mm", FPU & SveMode && HasMatmulFP32) + .Case("f64mm", FPU & SveMode && HasMatmulFP64) + .Case("sve2", FPU & SveMode && HasSVE2) + .Case("sve2-pmull128", FPU & SveMode && HasSVE2AES) + .Case("sve2-bitperm", FPU & SveMode && HasSVE2BitPerm) + .Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3) + .Case("sve2-sm4", FPU & SveMode && HasSVE2SM4) + .Case("sme", HasSME) + .Case("sme2", HasSME2) + .Case("sme-f64f64", HasSMEF64F64) + .Case("sme-i16i64", HasSMEI16I64) + .Case("sme-fa64", HasSMEFA64) + .Cases("memtag", "memtag2", HasMTE) + .Case("sb", HasSB) + .Case("predres", HasPredRes) + .Cases("ssbs", "ssbs2", HasSSBS) + .Case("bti", HasBTI) + .Cases("ls64", "ls64_v", "ls64_accdata", HasLS64) + .Case("wfxt", HasWFxT) + .Case("rcpc3", HasRCPC3) + .Default(false); +} + +void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, + StringRef Name, bool Enabled) const { + Features[Name] = Enabled; + // If the feature is an architecture feature (like v8.2a), add all previous + // architecture versions and any dependant target features. + const std::optional<llvm::AArch64::ArchInfo> ArchInfo = + llvm::AArch64::ArchInfo::findBySubArch(Name); + + if (!ArchInfo) + return; // Not an architecture, nothing more to do. + + // Disabling an architecture feature does not affect dependent features + if (!Enabled) + return; + + for (const auto *OtherArch : llvm::AArch64::ArchInfos) + if (ArchInfo->implies(*OtherArch)) + Features[OtherArch->getSubArch()] = true; + + // Set any features implied by the architecture + std::vector<StringRef> CPUFeats; + if (llvm::AArch64::getExtensionFeatures(ArchInfo->DefaultExts, CPUFeats)) { + for (auto F : CPUFeats) { + assert(F[0] == '+' && "Expected + in target feature!"); + Features[F.drop_front(1)] = true; + } + } } bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) { - FPU = FPUMode; - HasCRC = false; - HasCrypto = false; - HasAES = false; - HasSHA2 = false; - HasSHA3 = false; - HasSM4 = false; - HasUnaligned = true; - HasFullFP16 = false; - HasDotProd = false; - HasFP16FML = false; - HasMTE = false; - HasTME = false; - HasLS64 = false; - HasRandGen = false; - HasMatMul = false; - HasBFloat16 = false; - HasSVE2 = false; - HasSVE2AES = false; - HasSVE2SHA3 = false; - HasSVE2SM4 = false; - HasSVE2BitPerm = false; - HasMatmulFP64 = false; - HasMatmulFP32 = false; - HasLSE = false; - - ArchKind = llvm::AArch64::ArchKind::ARMV8A; - for (const auto &Feature : Features) { - if (Feature == "+neon") + if (Feature == "-fp-armv8") + HasNoFP = true; + if (Feature == "-neon") + HasNoNeon = true; + if (Feature == "-sve") + HasNoSVE = true; + + if (Feature == "+neon" || Feature == "+fp-armv8") + FPU |= NeonMode; + if (Feature == "+jscvt") { + HasJSCVT = true; + FPU |= NeonMode; + } + if (Feature == "+fcma") { + HasFCMA = true; FPU |= NeonMode; + } + if (Feature == "+sve") { + FPU |= NeonMode; FPU |= SveMode; - HasFullFP16 = 1; + HasFullFP16 = true; } if (Feature == "+sve2") { + FPU |= NeonMode; FPU |= SveMode; - HasFullFP16 = 1; - HasSVE2 = 1; + HasFullFP16 = true; + HasSVE2 = true; } if (Feature == "+sve2-aes") { + FPU |= NeonMode; FPU |= SveMode; - HasFullFP16 = 1; - HasSVE2 = 1; - HasSVE2AES = 1; + HasFullFP16 = true; + HasSVE2 = true; + HasSVE2AES = true; } if (Feature == "+sve2-sha3") { + FPU |= NeonMode; FPU |= SveMode; - HasFullFP16 = 1; - HasSVE2 = 1; - HasSVE2SHA3 = 1; + HasFullFP16 = true; + HasSVE2 = true; + HasSVE2SHA3 = true; } if (Feature == "+sve2-sm4") { + FPU |= NeonMode; FPU |= SveMode; - HasFullFP16 = 1; - HasSVE2 = 1; - HasSVE2SM4 = 1; + HasFullFP16 = true; + HasSVE2 = true; + HasSVE2SM4 = true; } if (Feature == "+sve2-bitperm") { + FPU |= NeonMode; FPU |= SveMode; - HasFullFP16 = 1; - HasSVE2 = 1; - HasSVE2BitPerm = 1; + HasFullFP16 = true; + HasSVE2 = true; + HasSVE2BitPerm = true; } if (Feature == "+f32mm") { + FPU |= NeonMode; FPU |= SveMode; + HasFullFP16 = true; HasMatmulFP32 = true; } if (Feature == "+f64mm") { + FPU |= NeonMode; FPU |= SveMode; + HasFullFP16 = true; HasMatmulFP64 = true; } + if (Feature == "+sme") { + HasSME = true; + HasBFloat16 = true; + HasFullFP16 = true; + } + if (Feature == "+sme2") { + HasSME = true; + HasSME2 = true; + HasBFloat16 = true; + HasFullFP16 = true; + } + if (Feature == "+sme-f64f64") { + HasSME = true; + HasSMEF64F64 = true; + HasBFloat16 = true; + HasFullFP16 = true; + } + if (Feature == "+sme-i16i64") { + HasSME = true; + HasSMEI16I64 = true; + HasBFloat16 = true; + HasFullFP16 = true; + } + if (Feature == "+sme-fa64") { + FPU |= NeonMode; + FPU |= SveMode; + HasSME = true; + HasSVE2 = true; + HasSMEFA64 = true; + } + if (Feature == "+sb") + HasSB = true; + if (Feature == "+predres") + HasPredRes = true; + if (Feature == "+ssbs") + HasSSBS = true; + if (Feature == "+bti") + HasBTI = true; + if (Feature == "+wfxt") + HasWFxT = true; + if (Feature == "-fmv") + HasFMV = false; if (Feature == "+crc") HasCRC = true; - if (Feature == "+crypto") - HasCrypto = true; - if (Feature == "+aes") + if (Feature == "+rcpc") + HasRCPC = true; + if (Feature == "+aes") { + FPU |= NeonMode; HasAES = true; - if (Feature == "+sha2") + } + if (Feature == "+sha2") { + FPU |= NeonMode; HasSHA2 = true; + } if (Feature == "+sha3") { + FPU |= NeonMode; HasSHA2 = true; HasSHA3 = true; } - if (Feature == "+sm4") + if (Feature == "+rdm") { + FPU |= NeonMode; + HasRDM = true; + } + if (Feature == "+dit") + HasDIT = true; + if (Feature == "+cccp") + HasCCPP = true; + if (Feature == "+ccdp") { + HasCCPP = true; + HasCCDP = true; + } + if (Feature == "+fptoint") + HasFRInt3264 = true; + if (Feature == "+sm4") { + FPU |= NeonMode; HasSM4 = true; + } if (Feature == "+strict-align") HasUnaligned = false; - if (Feature == "+v8.1a") - ArchKind = llvm::AArch64::ArchKind::ARMV8_1A; - if (Feature == "+v8.2a") - ArchKind = llvm::AArch64::ArchKind::ARMV8_2A; - if (Feature == "+v8.3a") - ArchKind = llvm::AArch64::ArchKind::ARMV8_3A; - if (Feature == "+v8.4a") - 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 == "+v8.7a") - ArchKind = llvm::AArch64::ArchKind::ARMV8_7A; + // All predecessor archs are added but select the latest one for ArchKind. + if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version) + ArchInfo = &llvm::AArch64::ARMV8A; + if (Feature == "+v8.1a" && + ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version) + ArchInfo = &llvm::AArch64::ARMV8_1A; + if (Feature == "+v8.2a" && + ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version) + ArchInfo = &llvm::AArch64::ARMV8_2A; + if (Feature == "+v8.3a" && + ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version) + ArchInfo = &llvm::AArch64::ARMV8_3A; + if (Feature == "+v8.4a" && + ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version) + ArchInfo = &llvm::AArch64::ARMV8_4A; + if (Feature == "+v8.5a" && + ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version) + ArchInfo = &llvm::AArch64::ARMV8_5A; + if (Feature == "+v8.6a" && + ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version) + ArchInfo = &llvm::AArch64::ARMV8_6A; + if (Feature == "+v8.7a" && + ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version) + ArchInfo = &llvm::AArch64::ARMV8_7A; + if (Feature == "+v8.8a" && + ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version) + ArchInfo = &llvm::AArch64::ARMV8_8A; + if (Feature == "+v8.9a" && + ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version) + ArchInfo = &llvm::AArch64::ARMV8_9A; + if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version) + ArchInfo = &llvm::AArch64::ARMV9A; + if (Feature == "+v9.1a" && + ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version) + ArchInfo = &llvm::AArch64::ARMV9_1A; + if (Feature == "+v9.2a" && + ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version) + ArchInfo = &llvm::AArch64::ARMV9_2A; + if (Feature == "+v9.3a" && + ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version) + ArchInfo = &llvm::AArch64::ARMV9_3A; + if (Feature == "+v9.4a" && + ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version) + ArchInfo = &llvm::AArch64::ARMV9_4A; + if (Feature == "+v9.5a" && + ArchInfo->Version < llvm::AArch64::ARMV9_5A.Version) + ArchInfo = &llvm::AArch64::ARMV9_5A; if (Feature == "+v8r") - ArchKind = llvm::AArch64::ArchKind::ARMV8R; - if (Feature == "+fullfp16") + ArchInfo = &llvm::AArch64::ARMV8R; + if (Feature == "+fullfp16") { + FPU |= NeonMode; HasFullFP16 = true; - if (Feature == "+dotprod") + } + if (Feature == "+dotprod") { + FPU |= NeonMode; HasDotProd = true; - if (Feature == "+fp16fml") + } + if (Feature == "+fp16fml") { + FPU |= NeonMode; + HasFullFP16 = true; HasFP16FML = true; + } if (Feature == "+mte") HasMTE = true; if (Feature == "+tme") @@ -565,10 +976,188 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasRandGen = true; if (Feature == "+flagm") HasFlagM = true; + if (Feature == "+altnzcv") { + HasFlagM = true; + HasAlternativeNZCV = true; + } + if (Feature == "+mops") + HasMOPS = true; + if (Feature == "+d128") + HasD128 = true; + if (Feature == "+gcs") + HasGCS = true; + if (Feature == "+rcpc3") + HasRCPC3 = true; + } + + // Check features that are manually disabled by command line options. + // This needs to be checked after architecture-related features are handled, + // making sure they are properly disabled when required. + for (const auto &Feature : Features) { + if (Feature == "-d128") + HasD128 = false; } setDataLayout(); + setArchFeatures(); + + if (HasNoFP) { + FPU &= ~FPUMode; + FPU &= ~NeonMode; + FPU &= ~SveMode; + } + if (HasNoNeon) { + FPU &= ~NeonMode; + FPU &= ~SveMode; + } + if (HasNoSVE) + FPU &= ~SveMode; + + return true; +} + +bool AArch64TargetInfo::initFeatureMap( + llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, + const std::vector<std::string> &FeaturesVec) const { + std::vector<std::string> UpdatedFeaturesVec; + // Parse the CPU and add any implied features. + std::optional<llvm::AArch64::CpuInfo> CpuInfo = llvm::AArch64::parseCpu(CPU); + if (CpuInfo) { + auto Exts = CpuInfo->getImpliedExtensions(); + std::vector<StringRef> CPUFeats; + llvm::AArch64::getExtensionFeatures(Exts, CPUFeats); + for (auto F : CPUFeats) { + assert((F[0] == '+' || F[0] == '-') && "Expected +/- in target feature!"); + UpdatedFeaturesVec.push_back(F.str()); + } + } + + // Process target and dependent features. This is done in two loops collecting + // them into UpdatedFeaturesVec: first to add dependent '+'features, second to + // add target '+/-'features that can later disable some of features added on + // the first loop. Function Multi Versioning features begin with '?'. + for (const auto &Feature : FeaturesVec) + if (((Feature[0] == '?' || Feature[0] == '+')) && + AArch64TargetInfo::doesFeatureAffectCodeGen(Feature.substr(1))) { + StringRef DepFeatures = + AArch64TargetInfo::getFeatureDependencies(Feature.substr(1)); + SmallVector<StringRef, 1> AttrFeatures; + DepFeatures.split(AttrFeatures, ","); + for (auto F : AttrFeatures) + UpdatedFeaturesVec.push_back(F.str()); + } + for (const auto &Feature : FeaturesVec) + if (Feature[0] != '?') { + std::string UpdatedFeature = Feature; + if (Feature[0] == '+') { + std::optional<llvm::AArch64::ExtensionInfo> Extension = + llvm::AArch64::parseArchExtension(Feature.substr(1)); + if (Extension) + UpdatedFeature = Extension->Feature.str(); + } + UpdatedFeaturesVec.push_back(UpdatedFeature); + } + + return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec); +} + +// Parse AArch64 Target attributes, which are a comma separated list of: +// "arch=<arch>" - parsed to features as per -march=.. +// "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu> +// "tune=<cpu>" - TuneCPU set to <cpu> +// "feature", "no-feature" - Add (or remove) feature. +// "+feature", "+nofeature" - Add (or remove) feature. +ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const { + ParsedTargetAttr Ret; + if (Features == "default") + return Ret; + SmallVector<StringRef, 1> AttrFeatures; + Features.split(AttrFeatures, ","); + bool FoundArch = false; + + auto SplitAndAddFeatures = [](StringRef FeatString, + std::vector<std::string> &Features) { + SmallVector<StringRef, 8> SplitFeatures; + FeatString.split(SplitFeatures, StringRef("+"), -1, false); + for (StringRef Feature : SplitFeatures) { + StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature); + if (!FeatureName.empty()) + Features.push_back(FeatureName.str()); + else + // Pushing the original feature string to give a sema error later on + // when they get checked. + if (Feature.starts_with("no")) + Features.push_back("-" + Feature.drop_front(2).str()); + else + Features.push_back("+" + Feature.str()); + } + }; + + for (auto &Feature : AttrFeatures) { + Feature = Feature.trim(); + if (Feature.starts_with("fpmath=")) + continue; + + if (Feature.starts_with("branch-protection=")) { + Ret.BranchProtection = Feature.split('=').second.trim(); + continue; + } + + if (Feature.starts_with("arch=")) { + if (FoundArch) + Ret.Duplicate = "arch="; + FoundArch = true; + std::pair<StringRef, StringRef> Split = + Feature.split("=").second.trim().split("+"); + const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Split.first); + + // Parse the architecture version, adding the required features to + // Ret.Features. + if (!AI) + continue; + Ret.Features.push_back(AI->ArchFeature.str()); + // Add any extra features, after the + + SplitAndAddFeatures(Split.second, Ret.Features); + } else if (Feature.starts_with("cpu=")) { + if (!Ret.CPU.empty()) + Ret.Duplicate = "cpu="; + else { + // Split the cpu string into "cpu=", "cortex-a710" and any remaining + // "+feat" features. + std::pair<StringRef, StringRef> Split = + Feature.split("=").second.trim().split("+"); + Ret.CPU = Split.first; + SplitAndAddFeatures(Split.second, Ret.Features); + } + } else if (Feature.starts_with("tune=")) { + if (!Ret.Tune.empty()) + Ret.Duplicate = "tune="; + else + Ret.Tune = Feature.split("=").second.trim(); + } else if (Feature.starts_with("+")) { + SplitAndAddFeatures(Feature, Ret.Features); + } else if (Feature.starts_with("no-")) { + StringRef FeatureName = + llvm::AArch64::getArchExtFeature(Feature.split("-").second); + if (!FeatureName.empty()) + Ret.Features.push_back("-" + FeatureName.drop_front(1).str()); + else + Ret.Features.push_back("-" + Feature.split("-").second.str()); + } else { + // Try parsing the string to the internal target feature name. If it is + // invalid, add the original string (which could already be an internal + // name). These should be checked later by isValidFeatureName. + StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature); + if (!FeatureName.empty()) + Ret.Features.push_back(FeatureName.str()); + else + Ret.Features.push_back("+" + Feature.str()); + } + } + return Ret; +} +bool AArch64TargetInfo::hasBFloat16Type() const { return true; } @@ -582,6 +1171,7 @@ AArch64TargetInfo::checkCallingConvention(CallingConv CC) const { case CC_PreserveAll: case CC_OpenCLKernel: case CC_AArch64VectorCall: + case CC_AArch64SVEPCS: case CC_Win64: return CCCR_OK; default: @@ -596,6 +1186,8 @@ TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const { } const char *const AArch64TargetInfo::GCCRegNames[] = { + // clang-format off + // 32-bit Integer registers "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22", @@ -628,11 +1220,20 @@ const char *const AArch64TargetInfo::GCCRegNames[] = { // SVE predicate registers "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10", - "p11", "p12", "p13", "p14", "p15" + "p11", "p12", "p13", "p14", "p15", + + // SVE predicate-as-counter registers + "pn0", "pn1", "pn2", "pn3", "pn4", "pn5", "pn6", "pn7", "pn8", + "pn9", "pn10", "pn11", "pn12", "pn13", "pn14", "pn15", + + // SME registers + "za", "zt0", + + // clang-format on }; ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = { @@ -675,7 +1276,53 @@ const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = { }; ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const { - return llvm::makeArrayRef(GCCRegAliases); + return llvm::ArrayRef(GCCRegAliases); +} + +// Returns the length of cc constraint. +static unsigned matchAsmCCConstraint(const char *Name) { + constexpr unsigned len = 5; + auto RV = llvm::StringSwitch<unsigned>(Name) + .Case("@cceq", len) + .Case("@ccne", len) + .Case("@cchs", len) + .Case("@cccs", len) + .Case("@cccc", len) + .Case("@cclo", len) + .Case("@ccmi", len) + .Case("@ccpl", len) + .Case("@ccvs", len) + .Case("@ccvc", len) + .Case("@cchi", len) + .Case("@ccls", len) + .Case("@ccge", len) + .Case("@cclt", len) + .Case("@ccgt", len) + .Case("@ccle", len) + .Default(0); + return RV; +} + +std::string +AArch64TargetInfo::convertConstraint(const char *&Constraint) const { + 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; + case '@': + if (const unsigned Len = matchAsmCCConstraint(Constraint)) { + std::string Converted = "{" + std::string(Constraint, Len) + "}"; + Constraint += Len - 1; + return Converted; + } + return std::string(1, *Constraint); + default: + R = TargetInfo::convertConstraint(Constraint); + break; + } + return R; } bool AArch64TargetInfo::validateAsmConstraint( @@ -702,8 +1349,15 @@ 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) + if (Name[1] == 'p' && + (Name[2] == 'l' || Name[2] == 'a' || Name[2] == 'h')) { + // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7, "Uph"=P8-P15) + Info.setAllowsRegister(); + Name += 2; + return true; + } + if (Name[1] == 'c' && (Name[2] == 'i' || Name[2] == 'j')) { + // Gpr registers ("Uci"=w8-11, "Ucj"=w12-15) Info.setAllowsRegister(); Name += 2; return true; @@ -725,6 +1379,13 @@ bool AArch64TargetInfo::validateAsmConstraint( case 'y': // SVE registers (V0-V7) Info.setAllowsRegister(); return true; + case '@': + // CC condition + if (const unsigned Len = matchAsmCCConstraint(Name)) { + Name += Len - 1; + Info.setAllowsRegister(); + return true; + } } return false; } @@ -733,8 +1394,7 @@ bool AArch64TargetInfo::validateConstraintModifier( StringRef Constraint, char Modifier, unsigned Size, std::string &SuggestedModifier) const { // Strip off constraint modifiers. - while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') - Constraint = Constraint.substr(1); + Constraint = Constraint.ltrim("=+&"); switch (Constraint[0]) { default: @@ -763,7 +1423,7 @@ bool AArch64TargetInfo::validateConstraintModifier( } } -const char *AArch64TargetInfo::getClobbers() const { return ""; } +std::string_view AArch64TargetInfo::getClobbers() const { return ""; } int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { if (RegNo == 0) @@ -872,7 +1532,13 @@ MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple, void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { WindowsARM64TargetInfo::getTargetDefines(Opts, Builder); - Builder.defineMacro("_M_ARM64", "1"); + if (getTriple().isWindowsArm64EC()) { + Builder.defineMacro("_M_X64", "100"); + Builder.defineMacro("_M_AMD64", "100"); + Builder.defineMacro("_M_ARM64EC", "1"); + } else { + Builder.defineMacro("_M_ARM64", "1"); + } } TargetInfo::CallingConvKind @@ -936,7 +1602,6 @@ void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts, else Builder.defineMacro("__ARM64_ARCH_8__"); Builder.defineMacro("__ARM_NEON__"); - Builder.defineMacro("__LITTLE_ENDIAN__"); Builder.defineMacro("__REGISTER_PREFIX__", ""); Builder.defineMacro("__arm64", "1"); Builder.defineMacro("__arm64__", "1"); diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h index 46882a808336..9699222b0bf7 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h @@ -15,7 +15,8 @@ #include "OSTargets.h" #include "clang/Basic/TargetBuiltins.h" -#include "llvm/Support/TargetParser.h" +#include "llvm/TargetParser/AArch64TargetParser.h" +#include <optional> namespace clang { namespace targets { @@ -25,38 +26,67 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { static const TargetInfo::GCCRegAlias GCCRegAliases[]; static const char *const GCCRegNames[]; - enum FPUModeEnum { FPUMode, NeonMode = (1 << 0), SveMode = (1 << 1) }; - - unsigned FPU; - bool HasCRC; - bool HasCrypto; - bool HasAES; - bool HasSHA2; - bool HasSHA3; - bool HasSM4; - bool HasUnaligned; - bool HasFullFP16; - bool HasDotProd; - bool HasFP16FML; - bool HasMTE; - bool HasTME; - bool HasPAuth; - bool HasLS64; - bool HasRandGen; - bool HasMatMul; - bool HasSVE2; - bool HasSVE2AES; - bool HasSVE2SHA3; - bool HasSVE2SM4; - bool HasSVE2BitPerm; - bool HasMatmulFP64; - bool HasMatmulFP32; - bool HasLSE; - bool HasFlagM; - - llvm::AArch64::ArchKind ArchKind; - - static const Builtin::Info BuiltinInfo[]; + enum FPUModeEnum { + FPUMode = (1 << 0), + NeonMode = (1 << 1), + SveMode = (1 << 2), + }; + + unsigned FPU = FPUMode; + bool HasCRC = false; + bool HasAES = false; + bool HasSHA2 = false; + bool HasSHA3 = false; + bool HasSM4 = false; + bool HasUnaligned = true; + bool HasFullFP16 = false; + bool HasDotProd = false; + bool HasFP16FML = false; + bool HasMTE = false; + bool HasTME = false; + bool HasPAuth = false; + bool HasLS64 = false; + bool HasRandGen = false; + bool HasMatMul = false; + bool HasBFloat16 = false; + bool HasSVE2 = false; + bool HasSVE2AES = false; + bool HasSVE2SHA3 = false; + bool HasSVE2SM4 = false; + bool HasSVE2BitPerm = false; + bool HasMatmulFP64 = false; + bool HasMatmulFP32 = false; + bool HasLSE = false; + bool HasFlagM = false; + bool HasAlternativeNZCV = false; + bool HasMOPS = false; + bool HasD128 = false; + bool HasRCPC = false; + bool HasRDM = false; + bool HasDIT = false; + bool HasCCPP = false; + bool HasCCDP = false; + bool HasFRInt3264 = false; + bool HasSME = false; + bool HasSME2 = false; + bool HasSMEF64F64 = false; + bool HasSMEI16I64 = false; + bool HasSB = false; + bool HasPredRes = false; + bool HasSSBS = false; + bool HasBTI = false; + bool HasWFxT = false; + bool HasJSCVT = false; + bool HasFCMA = false; + bool HasNoFP = false; + bool HasNoNeon = false; + bool HasNoSVE = false; + bool HasFMV = true; + bool HasGCS = false; + bool HasRCPC3 = false; + bool HasSMEFA64 = false; + + const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A; std::string ABI; @@ -66,17 +96,27 @@ public: StringRef getABI() const override; bool setABI(const std::string &Name) override; - bool validateBranchProtection(StringRef, BranchProtectionInfo &, - StringRef &) const override; + bool validateBranchProtection(StringRef Spec, StringRef Arch, + BranchProtectionInfo &BPI, + StringRef &Err) const override; bool isValidCPUName(StringRef Name) const override; void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; bool setCPU(const std::string &Name) override; + unsigned multiVersionSortPriority(StringRef Name) const override; + unsigned multiVersionFeatureCost() const override; + + bool + initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, + StringRef CPU, + const std::vector<std::string> &FeaturesVec) const override; bool useFP16ConversionIntrinsics() const override { return false; } + void setArchFeatures(); + void getTargetDefinesARMV81A(const LangOptions &Opts, MacroBuilder &Builder) const; void getTargetDefinesARMV82A(const LangOptions &Opts, @@ -91,14 +131,43 @@ public: MacroBuilder &Builder) const; void getTargetDefinesARMV87A(const LangOptions &Opts, MacroBuilder &Builder) const; + void getTargetDefinesARMV88A(const LangOptions &Opts, + MacroBuilder &Builder) const; + void getTargetDefinesARMV89A(const LangOptions &Opts, + MacroBuilder &Builder) const; + void getTargetDefinesARMV9A(const LangOptions &Opts, + MacroBuilder &Builder) const; + void getTargetDefinesARMV91A(const LangOptions &Opts, + MacroBuilder &Builder) const; + void getTargetDefinesARMV92A(const LangOptions &Opts, + MacroBuilder &Builder) const; + void getTargetDefinesARMV93A(const LangOptions &Opts, + MacroBuilder &Builder) const; + void getTargetDefinesARMV94A(const LangOptions &Opts, + MacroBuilder &Builder) const; + void getTargetDefinesARMV95A(const LangOptions &Opts, + MacroBuilder &Builder) const; void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; ArrayRef<Builtin::Info> getTargetBuiltins() const override; + std::optional<std::pair<unsigned, unsigned>> + getVScaleRange(const LangOptions &LangOpts) const override; + bool doesFeatureAffectCodeGen(StringRef Name) const override; + StringRef getFeatureDependencies(StringRef Name) const override; + bool validateCpuSupports(StringRef FeatureStr) const override; bool hasFeature(StringRef Feature) const override; + void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, + bool Enabled) const override; bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override; + ParsedTargetAttr parseTargetAttr(StringRef Str) const override; + bool supportsTargetAttributeTune() const override { return true; } + + bool checkArithmeticFenceSupported() const override { return true; } + + bool hasBFloat16Type() const override; CallingConvCheckResult checkCallingConvention(CallingConv CC) const override; @@ -109,26 +178,14 @@ 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; - } + std::string convertConstraint(const char *&Constraint) const override; bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override; bool validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size, std::string &SuggestedModifier) const override; - const char *getClobbers() const override; + std::string_view getClobbers() const override; StringRef getConstraintRegister(StringRef Constraint, StringRef Expression) const override { @@ -140,7 +197,7 @@ public: const char *getBFloat16Mangling() const override { return "u6__bf16"; }; bool hasInt128Type() const override; - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } }; class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo { diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.cpp index fac786dbcf9e..6f3a4908623d 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.cpp @@ -13,12 +13,10 @@ #include "AMDGPU.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/LangOptions.h" #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; @@ -34,63 +32,66 @@ static const char *const DataLayoutStringR600 = static const char *const DataLayoutStringAMDGCN = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32" - "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" + "-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:" + "32-v48:64-v96:128" "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1" - "-ni:7"; + "-ni:7:8:9"; const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = { - Generic, // Default - Global, // opencl_global - Local, // opencl_local - Constant, // opencl_constant - Private, // opencl_private - Generic, // opencl_generic - Global, // opencl_global_device - Global, // opencl_global_host - Global, // cuda_device - Constant, // cuda_constant - Local, // cuda_shared - Global, // sycl_global - Global, // sycl_global_device - Global, // sycl_global_host - Local, // sycl_local - Private, // sycl_private - Generic, // ptr32_sptr - Generic, // ptr32_uptr - Generic // ptr64 + llvm::AMDGPUAS::FLAT_ADDRESS, // Default + llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global + llvm::AMDGPUAS::LOCAL_ADDRESS, // opencl_local + llvm::AMDGPUAS::CONSTANT_ADDRESS, // opencl_constant + llvm::AMDGPUAS::PRIVATE_ADDRESS, // opencl_private + llvm::AMDGPUAS::FLAT_ADDRESS, // opencl_generic + llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_device + llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_host + llvm::AMDGPUAS::GLOBAL_ADDRESS, // cuda_device + llvm::AMDGPUAS::CONSTANT_ADDRESS, // cuda_constant + llvm::AMDGPUAS::LOCAL_ADDRESS, // cuda_shared + llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global + llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global_device + llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global_host + llvm::AMDGPUAS::LOCAL_ADDRESS, // sycl_local + llvm::AMDGPUAS::PRIVATE_ADDRESS, // sycl_private + llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr + llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr + llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 + llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared }; const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { - Private, // Default - Global, // opencl_global - Local, // opencl_local - Constant, // opencl_constant - Private, // opencl_private - Generic, // opencl_generic - Global, // opencl_global_device - Global, // opencl_global_host - Global, // cuda_device - Constant, // cuda_constant - Local, // cuda_shared + llvm::AMDGPUAS::PRIVATE_ADDRESS, // Default + llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global + llvm::AMDGPUAS::LOCAL_ADDRESS, // opencl_local + llvm::AMDGPUAS::CONSTANT_ADDRESS, // opencl_constant + llvm::AMDGPUAS::PRIVATE_ADDRESS, // opencl_private + llvm::AMDGPUAS::FLAT_ADDRESS, // opencl_generic + llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_device + llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_host + llvm::AMDGPUAS::GLOBAL_ADDRESS, // cuda_device + llvm::AMDGPUAS::CONSTANT_ADDRESS, // cuda_constant + llvm::AMDGPUAS::LOCAL_ADDRESS, // cuda_shared // SYCL address space values for this map are dummy - Generic, // sycl_global - Generic, // sycl_global_device - Generic, // sycl_global_host - Generic, // sycl_local - Generic, // sycl_private - Generic, // ptr32_sptr - Generic, // ptr32_uptr - Generic // ptr64 + llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global + llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_device + llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_host + llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_local + llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_private + llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr + llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr + llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 + llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared }; } // namespace targets } // namespace clang -const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = { +static constexpr Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsAMDGPU.def" }; @@ -172,7 +173,7 @@ const char *const AMDGPUTargetInfo::GCCRegNames[] = { }; ArrayRef<const char *> AMDGPUTargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } bool AMDGPUTargetInfo::initFeatureMap( @@ -180,136 +181,18 @@ bool AMDGPUTargetInfo::initFeatureMap( const std::vector<std::string> &FeatureVec) const { using namespace llvm::AMDGPU; - - // XXX - What does the member GPU mean if device name string passed here? - if (isAMDGCN(getTriple())) { - switch (llvm::AMDGPU::parseArchAMDGCN(CPU)) { - case GK_GFX1035: - case GK_GFX1034: - case GK_GFX1033: - case GK_GFX1032: - case GK_GFX1031: - case GK_GFX1030: - Features["ci-insts"] = true; - Features["dot1-insts"] = true; - Features["dot2-insts"] = true; - Features["dot5-insts"] = true; - Features["dot6-insts"] = true; - Features["dot7-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; - Features["s-memtime-inst"] = true; - break; - case GK_GFX1012: - case GK_GFX1011: - Features["dot1-insts"] = true; - Features["dot2-insts"] = true; - Features["dot5-insts"] = true; - Features["dot6-insts"] = true; - Features["dot7-insts"] = true; - LLVM_FALLTHROUGH; - case GK_GFX1013: - case GK_GFX1010: - Features["dl-insts"] = true; - Features["ci-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["s-memrealtime"] = true; - Features["s-memtime-inst"] = true; - break; - case GK_GFX90A: - Features["gfx90a-insts"] = true; - LLVM_FALLTHROUGH; - case GK_GFX908: - Features["dot3-insts"] = true; - 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; - Features["dot1-insts"] = true; - Features["dot2-insts"] = true; - Features["dot7-insts"] = true; - LLVM_FALLTHROUGH; - case GK_GFX90C: - case GK_GFX909: - case GK_GFX904: - case GK_GFX902: - case GK_GFX900: - Features["gfx9-insts"] = true; - LLVM_FALLTHROUGH; - case GK_GFX810: - case GK_GFX805: - case GK_GFX803: - case GK_GFX802: - case GK_GFX801: - Features["gfx8-insts"] = true; - Features["16-bit-insts"] = true; - Features["dpp"] = true; - Features["s-memrealtime"] = true; - LLVM_FALLTHROUGH; - case GK_GFX705: - case GK_GFX704: - case GK_GFX703: - case GK_GFX702: - case GK_GFX701: - case GK_GFX700: - Features["ci-insts"] = true; - Features["flat-address-space"] = true; - LLVM_FALLTHROUGH; - case GK_GFX602: - case GK_GFX601: - case GK_GFX600: - Features["s-memtime-inst"] = true; - break; - case GK_NONE: - break; - default: - llvm_unreachable("Unhandled GPU!"); - } - } else { - if (CPU.empty()) - CPU = "r600"; - - switch (llvm::AMDGPU::parseArchR600(CPU)) { - case GK_CAYMAN: - case GK_CYPRESS: - case GK_RV770: - case GK_RV670: - // TODO: Add fp64 when implemented. - break; - case GK_TURKS: - case GK_CAICOS: - case GK_BARTS: - case GK_SUMO: - case GK_REDWOOD: - case GK_JUNIPER: - case GK_CEDAR: - case GK_RV730: - case GK_RV710: - case GK_RS880: - case GK_R630: - case GK_R600: - break; - default: - llvm_unreachable("Unhandled GPU!"); - } + fillAMDGPUFeatureMap(CPU, getTriple(), Features); + if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec)) + return false; + + // TODO: Should move this logic into TargetParser + std::string ErrorMsg; + if (!insertWaveSizeFeature(CPU, getTriple(), Features, ErrorMsg)) { + Diags.Report(diag::err_invalid_feature_combination) << ErrorMsg; + return false; } - return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec); + return true; } void AMDGPUTargetInfo::fillValidCPUList( @@ -335,19 +218,24 @@ AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple, llvm::AMDGPU::getArchAttrR600(GPUKind)) { resetDataLayout(isAMDGCN(getTriple()) ? DataLayoutStringAMDGCN : DataLayoutStringR600); - GridValues = llvm::omp::AMDGPUGpuGridValues; setAddressSpaceMap(Triple.getOS() == llvm::Triple::Mesa3D || !isAMDGCN(Triple)); UseAddrSpaceMapMangling = true; + if (isAMDGCN(Triple)) { + // __bf16 is always available as a load/store only type on AMDGCN. + BFloat16Width = BFloat16Align = 16; + BFloat16Format = &llvm::APFloat::BFloat(); + } + HasLegalHalfType = true; HasFloat16 = true; WavefrontSize = GPUFeatures & llvm::AMDGPU::FEATURE_WAVE32 ? 32 : 64; AllowAMDGPUUnsafeFPAtomics = Opts.AllowAMDGPUUnsafeFPAtomics; - // Set pointer width and alignment for target address space 0. - PointerWidth = PointerAlign = getPointerWidthV(Generic); + // Set pointer width and alignment for the generic address space. + PointerWidth = PointerAlign = getPointerWidthV(LangAS::Default); if (getMaxPointerWidth() == 64) { LongWidth = LongAlign = 64; SizeType = UnsignedLong; @@ -356,6 +244,10 @@ AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple, } MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + CUMode = !(GPUFeatures & llvm::AMDGPU::FEATURE_WGP); + for (auto F : {"image-insts", "gws"}) + ReadOnlyFeatures.insert(F); + HalfArgsAndReturns = true; } void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { @@ -368,8 +260,8 @@ void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { } ArrayRef<Builtin::Info> AMDGPUTargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfo, clang::AMDGPU::LastTSBuiltin - - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfo, + clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin); } void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts, @@ -386,12 +278,17 @@ void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts, StringRef CanonName = isAMDGCN(getTriple()) ? getArchNameAMDGCN(GPUKind) : getArchNameR600(GPUKind); Builder.defineMacro(Twine("__") + Twine(CanonName) + Twine("__")); + // Emit macros for gfx family e.g. gfx906 -> __GFX9__, gfx1030 -> __GFX10___ + if (isAMDGCN(getTriple())) { + assert(CanonName.starts_with("gfx") && "Invalid amdgcn canonical name"); + Builder.defineMacro(Twine("__") + Twine(CanonName.drop_back(2).upper()) + + Twine("__")); + } if (isAMDGCN(getTriple())) { Builder.defineMacro("__amdgcn_processor__", Twine("\"") + Twine(CanonName) + Twine("\"")); Builder.defineMacro("__amdgcn_target_id__", - Twine("\"") + Twine(getTargetID().getValue()) + - Twine("\"")); + Twine("\"") + Twine(*getTargetID()) + Twine("\"")); for (auto F : getAllPossibleTargetIDFeatures(getTriple(), CanonName)) { auto Loc = OffloadArchFeatures.find(F); if (Loc != OffloadArchFeatures.end()) { @@ -405,6 +302,9 @@ void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts, } } + if (AllowAMDGPUUnsafeFPAtomics) + Builder.defineMacro("__AMDGCN_UNSAFE_FP_ATOMICS__"); + // TODO: __HAS_FMAF__, __HAS_LDEXPF__, __HAS_FP64__ are deprecated and will be // removed in the near future. if (hasFMAF()) @@ -418,7 +318,10 @@ void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts, if (hasFastFMA()) Builder.defineMacro("FP_FAST_FMA"); + Builder.defineMacro("__AMDGCN_WAVEFRONT_SIZE__", Twine(WavefrontSize)); + // ToDo: deprecate this macro for naming consistency. Builder.defineMacro("__AMDGCN_WAVEFRONT_SIZE", Twine(WavefrontSize)); + Builder.defineMacro("__AMDGCN_CUMODE__", Twine(CUMode)); } void AMDGPUTargetInfo::setAuxTarget(const TargetInfo *Aux) { @@ -431,9 +334,13 @@ void AMDGPUTargetInfo::setAuxTarget(const TargetInfo *Aux) { // supported by AMDGPU. Therefore keep its own format for these two types. auto SaveLongDoubleFormat = LongDoubleFormat; auto SaveFloat128Format = Float128Format; + auto SaveLongDoubleWidth = LongDoubleWidth; + auto SaveLongDoubleAlign = LongDoubleAlign; copyAuxTarget(Aux); LongDoubleFormat = SaveLongDoubleFormat; Float128Format = SaveFloat128Format; + LongDoubleWidth = SaveLongDoubleWidth; + LongDoubleAlign = SaveLongDoubleAlign; // 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. diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h b/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h index 2e580ecf2425..90a1516ecdd2 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h @@ -17,25 +17,19 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "llvm/ADT/StringSet.h" -#include "llvm/ADT/Triple.h" +#include "llvm/Support/AMDGPUAddrSpace.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/TargetParser.h" +#include "llvm/TargetParser/TargetParser.h" +#include "llvm/TargetParser/Triple.h" +#include <optional> namespace clang { namespace targets { class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { - static const Builtin::Info BuiltinInfo[]; static const char *const GCCRegNames[]; - enum AddrSpace { - Generic = 0, - Global = 1, - Local = 3, - Constant = 4, - Private = 5 - }; static const LangASMap AMDGPUDefIsGenMap; static const LangASMap AMDGPUDefIsPrivMap; @@ -43,6 +37,12 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { unsigned GPUFeatures; unsigned WavefrontSize; + /// Whether to use cumode or WGP mode. True for cumode. False for WGP mode. + bool CUMode; + + /// Whether having image instructions. + bool HasImage = false; + /// Target ID is device name followed by optional feature name postfixed /// by plus or minus sign delimitted by colon, e.g. gfx908:xnack+:sramecc-. /// If the target ID contains feature+, map it to true. @@ -95,17 +95,19 @@ public: void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override; - uint64_t getPointerWidthV(unsigned AddrSpace) const override { + uint64_t getPointerWidthV(LangAS AS) const override { if (isR600(getTriple())) return 32; + unsigned TargetAS = getTargetAddressSpace(AS); - if (AddrSpace == Private || AddrSpace == Local) + if (TargetAS == llvm::AMDGPUAS::PRIVATE_ADDRESS || + TargetAS == llvm::AMDGPUAS::LOCAL_ADDRESS) return 32; return 64; } - uint64_t getPointerAlignV(unsigned AddrSpace) const override { + uint64_t getPointerAlignV(LangAS AddrSpace) const override { return getPointerWidthV(AddrSpace); } @@ -113,12 +115,14 @@ public: return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32; } - const char *getClobbers() const override { return ""; } + bool hasBFloat16Type() const override { return isAMDGCN(getTriple()); } + + std::string_view getClobbers() const override { return ""; } ArrayRef<const char *> getGCCRegNames() const override; ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { - return None; + return std::nullopt; } /// Accepted register names: (n, m is unsigned integer, n < m) @@ -165,10 +169,8 @@ public: } bool HasLeftParen = false; - if (S.front() == '{') { + if (S.consume_front("{")) HasLeftParen = true; - S = S.drop_front(); - } if (S.empty()) return false; if (S.front() != 'v' && S.front() != 's' && S.front() != 'a') { @@ -195,29 +197,24 @@ public: return true; } bool HasLeftBracket = false; - if (!S.empty() && S.front() == '[') { + if (S.consume_front("[")) HasLeftBracket = true; - S = S.drop_front(); - } unsigned long long N; if (S.empty() || consumeUnsignedInteger(S, 10, N)) return false; - if (!S.empty() && S.front() == ':') { + if (S.consume_front(":")) { if (!HasLeftBracket) return false; - S = S.drop_front(); unsigned long long M; if (consumeUnsignedInteger(S, 10, M) || N >= M) return false; } if (HasLeftBracket) { - if (S.empty() || S.front() != ']') + if (!S.consume_front("]")) return false; - S = S.drop_front(); } - if (S.empty() || S.front() != '}') + if (!S.consume_front("}")) return false; - S = S.drop_front(); if (!S.empty()) return false; // Found {vn}, {sn}, {an}, {v[n]}, {s[n]}, {a[n]}, {v[n:m]}, {s[n:m]} @@ -352,34 +349,56 @@ public: } LangAS getCUDABuiltinAddressSpace(unsigned AS) const override { - return LangAS::Default; + switch (AS) { + case 0: + return LangAS::Default; + case 1: + return LangAS::cuda_device; + case 3: + return LangAS::cuda_shared; + case 4: + return LangAS::cuda_constant; + default: + return getLangASFromTargetAS(AS); + } + } + + std::optional<LangAS> getConstantAddressSpace() const override { + return getLangASFromTargetAS(llvm::AMDGPUAS::CONSTANT_ADDRESS); } - llvm::Optional<LangAS> getConstantAddressSpace() const override { - return getLangASFromTargetAS(Constant); + const llvm::omp::GV &getGridValue() const override { + switch (WavefrontSize) { + case 32: + return llvm::omp::getAMDGPUGridValues<32>(); + case 64: + return llvm::omp::getAMDGPUGridValues<64>(); + default: + llvm_unreachable("getGridValue not implemented for this wavesize"); + } } /// \returns Target specific vtbl ptr address space. unsigned getVtblPtrAddressSpace() const override { - return static_cast<unsigned>(Constant); + return static_cast<unsigned>(llvm::AMDGPUAS::CONSTANT_ADDRESS); } /// \returns If a target requires an address within a target specific address /// space \p AddressSpace to be converted in order to be used, then return the /// corresponding target specific DWARF address space. /// - /// \returns Otherwise return None and no conversion will be emitted in the - /// DWARF. - Optional<unsigned> + /// \returns Otherwise return std::nullopt and no conversion will be emitted + /// in the DWARF. + std::optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace) const override { const unsigned DWARF_Private = 1; const unsigned DWARF_Local = 2; - if (AddressSpace == Private) { + if (AddressSpace == llvm::AMDGPUAS::PRIVATE_ADDRESS) { return DWARF_Private; - } else if (AddressSpace == Local) { + } else if (AddressSpace == llvm::AMDGPUAS::LOCAL_ADDRESS) { return DWARF_Local; } else { - return None; + return std::nullopt; } } @@ -389,6 +408,7 @@ public: return CCCR_Warning; case CC_C: case CC_OpenCLKernel: + case CC_AMDGPUKernelCall: return CCCR_OK; } } @@ -404,7 +424,7 @@ public: void setAuxTarget(const TargetInfo *Aux) override; - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } // Record offload arch features since they are needed for defining the // pre-defined macros. @@ -412,23 +432,29 @@ public: DiagnosticsEngine &Diags) override { auto TargetIDFeatures = getAllPossibleTargetIDFeatures(getTriple(), getArchNameAMDGCN(GPUKind)); - llvm::for_each(Features, [&](const auto &F) { + for (const auto &F : Features) { assert(F.front() == '+' || F.front() == '-'); if (F == "+wavefrontsize64") WavefrontSize = 64; + else if (F == "+cumode") + CUMode = true; + else if (F == "-cumode") + CUMode = false; + else if (F == "+image-insts") + HasImage = true; bool IsOn = F.front() == '+'; StringRef Name = StringRef(F).drop_front(); - if (llvm::find(TargetIDFeatures, Name) == TargetIDFeatures.end()) - return; - assert(OffloadArchFeatures.find(Name) == OffloadArchFeatures.end()); + if (!llvm::is_contained(TargetIDFeatures, Name)) + continue; + assert(!OffloadArchFeatures.contains(Name)); OffloadArchFeatures[Name] = IsOn; - }); + } return true; } - Optional<std::string> getTargetID() const override { + std::optional<std::string> getTargetID() const override { if (!isAMDGCN(getTriple())) - return llvm::None; + return std::nullopt; // When -target-cpu is not set, we assume generic code that it is valid // for all GPU and use an empty string as target ID to represent that. if (GPUKind == llvm::AMDGPU::GK_NONE) @@ -436,6 +462,8 @@ public: return getCanonicalTargetID(getArchNameAMDGCN(GPUKind), OffloadArchFeatures); } + + bool hasHIPImageSupport() const override { return HasImage; } }; } // namespace targets diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/ARC.h b/contrib/llvm-project/clang/lib/Basic/Targets/ARC.h index b314c42be1e9..fcbfdd6eec58 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/ARC.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/ARC.h @@ -15,8 +15,8 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { @@ -40,13 +40,15 @@ public: void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return std::nullopt; + } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; } - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } ArrayRef<const char *> getGCCRegNames() const override { static const char *const GCCRegNames[] = { @@ -54,11 +56,11 @@ public: "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "gp", "sp", "fp", "ilink1", "r30", "blink"}; - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { - return None; + return std::nullopt; } bool validateAsmConstraint(const char *&Name, @@ -66,7 +68,9 @@ public: return false; } - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } + + bool isCLZForZeroUndef() const override { return false; } }; } // namespace targets diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp index 0e4048f8d5ff..55b71557452f 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/TargetParser/ARMTargetParser.h" using namespace clang; using namespace clang::targets; @@ -212,6 +213,22 @@ StringRef ARMTargetInfo::getCPUAttr() const { return "8_6A"; case llvm::ARM::ArchKind::ARMV8_7A: return "8_7A"; + case llvm::ARM::ArchKind::ARMV8_8A: + return "8_8A"; + case llvm::ARM::ArchKind::ARMV8_9A: + return "8_9A"; + case llvm::ARM::ArchKind::ARMV9A: + return "9A"; + case llvm::ARM::ArchKind::ARMV9_1A: + return "9_1A"; + case llvm::ARM::ArchKind::ARMV9_2A: + return "9_2A"; + case llvm::ARM::ArchKind::ARMV9_3A: + return "9_3A"; + case llvm::ARM::ArchKind::ARMV9_4A: + return "9_4A"; + case llvm::ARM::ArchKind::ARMV9_5A: + return "9_5A"; case llvm::ARM::ArchKind::ARMV8MBaseline: return "8M_BASE"; case llvm::ARM::ArchKind::ARMV8MMainline: @@ -240,8 +257,11 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0), HW_FP(0) { + bool IsFreeBSD = Triple.isOSFreeBSD(); bool IsOpenBSD = Triple.isOSOpenBSD(); bool IsNetBSD = Triple.isOSNetBSD(); + bool IsHaiku = Triple.isOSHaiku(); + bool IsOHOS = Triple.isOHOSFamily(); // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like // environment where size_t is `unsigned long` rather than `unsigned int` @@ -295,6 +315,7 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, case llvm::Triple::GNUEABIHF: case llvm::Triple::MuslEABI: case llvm::Triple::MuslEABIHF: + case llvm::Triple::OpenHOS: setABI("aapcs-linux"); break; case llvm::Triple::EABIHF: @@ -307,7 +328,7 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, default: if (IsNetBSD) setABI("apcs-gnu"); - else if (IsOpenBSD) + else if (IsFreeBSD || IsOpenBSD || IsHaiku || IsOHOS) setABI("aapcs-linux"); else setABI("aapcs"); @@ -361,6 +382,50 @@ bool ARMTargetInfo::setABI(const std::string &Name) { return false; } +bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const { + llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch); + if (CPUArch == llvm::ARM::ArchKind::INVALID) + CPUArch = llvm::ARM::parseArch(getTriple().getArchName()); + + if (CPUArch == llvm::ARM::ArchKind::INVALID) + return false; + + StringRef ArchFeature = llvm::ARM::getArchName(CPUArch); + auto a = + llvm::Triple(ArchFeature, getTriple().getVendorName(), + getTriple().getOSName(), getTriple().getEnvironmentName()); + + StringRef SubArch = llvm::ARM::getSubArch(CPUArch); + llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch); + return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M); +} + +bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch, + BranchProtectionInfo &BPI, + StringRef &Err) const { + llvm::ARM::ParsedBranchProtection PBP; + if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err)) + return false; + + if (!isBranchProtectionSupportedArch(Arch)) + return false; + + BPI.SignReturnAddr = + llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope) + .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf) + .Case("all", LangOptions::SignReturnAddressScopeKind::All) + .Default(LangOptions::SignReturnAddressScopeKind::None); + + // Don't care for the sign key, beyond issuing a warning. + if (PBP.Key == "b_key") + Err = "b-key"; + BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey; + + BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; + BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR; + return true; +} + // FIXME: This should be based on Arch attributes, not CPU names. bool ARMTargetInfo::initFeatureMap( llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, @@ -378,10 +443,23 @@ bool ARMTargetInfo::initFeatureMap( if (CPUArch != llvm::ARM::ArchKind::INVALID) { ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str(); TargetFeatures.push_back(ArchFeature); + + // These features are added to allow arm_neon.h target(..) attributes to + // match with both arm and aarch64. We need to add all previous architecture + // versions, so that "8.6" also allows "8.1" functions. In case of v9.x the + // v8.x counterparts are added too. We only need these for anything > 8.0-A. + for (llvm::ARM::ArchKind I = llvm::ARM::convertV9toV8(CPUArch); + I != llvm::ARM::ArchKind::INVALID; --I) + Features[llvm::ARM::getSubArch(I)] = true; + if (CPUArch > llvm::ARM::ArchKind::ARMV8A && + CPUArch <= llvm::ARM::ArchKind::ARMV9_3A) + for (llvm::ARM::ArchKind I = CPUArch; I != llvm::ARM::ArchKind::INVALID; + --I) + Features[llvm::ARM::getSubArch(I)] = true; } // get default FPU features - unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch); + llvm::ARM::FPUKind FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch); llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures); // get default Extension features @@ -437,9 +515,13 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HWDiv = 0; DotProd = 0; HasMatMul = 0; + HasPAC = 0; + HasBTI = 0; HasFloat16 = true; ARMCDECoprocMask = 0; HasBFloat16 = false; + HasFullBFloat16 = false; + FPRegsDisabled = false; // This does not diagnose illegal cases like having both // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64". @@ -516,9 +598,18 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, ARMCDECoprocMask |= (1U << Coproc); } else if (Feature == "+bf16") { HasBFloat16 = true; + } else if (Feature == "-fpregs") { + FPRegsDisabled = true; + } else if (Feature == "+pacbti") { + HasPAC = 1; + HasBTI = 1; + } else if (Feature == "+fullbf16") { + HasFullBFloat16 = true; } } + HalfArgsAndReturns = true; + switch (ArchVersion) { case 6: if (ArchProfile == llvm::ARM::ProfileKind::M) @@ -535,6 +626,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; break; case 8: + case 9: LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; } @@ -566,7 +658,8 @@ bool ARMTargetInfo::hasFeature(StringRef Feature) const { } bool ARMTargetInfo::hasBFloat16Type() const { - return HasBFloat16 && !SoftFloat; + // The __bf16 type is generally available so long as we have any fp registers. + return HasBFloat16 || (FPU && !SoftFloat); } bool ARMTargetInfo::isValidCPUName(StringRef Name) const { @@ -627,8 +720,10 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, // For bare-metal none-eabi. if (getTriple().getOS() == llvm::Triple::UnknownOS && (getTriple().getEnvironment() == llvm::Triple::EABI || - getTriple().getEnvironment() == llvm::Triple::EABIHF)) - Builder.defineMacro("__ELF__"); + getTriple().getEnvironment() == llvm::Triple::EABIHF) && + Opts.CPlusPlus) { + Builder.defineMacro("_GNU_SOURCE"); + } // Target properties. Builder.defineMacro("__REGISTER_PREFIX__", ""); @@ -736,7 +831,7 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16") Builder.defineMacro("__ARM_PCS_VFP", "1"); - if (SoftFloat) + if (SoftFloat || (SoftFloatABI && !FPU)) Builder.defineMacro("__SOFTFP__"); // ACLE position independent code macros. @@ -745,6 +840,70 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, if (Opts.RWPI) Builder.defineMacro("__ARM_RWPI", "1"); + // Macros for enabling co-proc intrinsics + uint64_t FeatureCoprocBF = 0; + switch (ArchKind) { + default: + break; + case llvm::ARM::ArchKind::ARMV4: + case llvm::ARM::ArchKind::ARMV4T: + // Filter __arm_ldcl and __arm_stcl in acle.h + FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1; + break; + case llvm::ARM::ArchKind::ARMV5T: + FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1 | FEATURE_COPROC_B2; + break; + case llvm::ARM::ArchKind::ARMV5TE: + case llvm::ARM::ArchKind::ARMV5TEJ: + if (!isThumb()) + FeatureCoprocBF = + FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | FEATURE_COPROC_B3; + break; + case llvm::ARM::ArchKind::ARMV6: + case llvm::ARM::ArchKind::ARMV6K: + case llvm::ARM::ArchKind::ARMV6KZ: + case llvm::ARM::ArchKind::ARMV6T2: + if (!isThumb() || ArchKind == llvm::ARM::ArchKind::ARMV6T2) + FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | + FEATURE_COPROC_B3 | FEATURE_COPROC_B4; + break; + case llvm::ARM::ArchKind::ARMV7A: + case llvm::ARM::ArchKind::ARMV7R: + case llvm::ARM::ArchKind::ARMV7M: + case llvm::ARM::ArchKind::ARMV7S: + case llvm::ARM::ArchKind::ARMV7EM: + FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | + FEATURE_COPROC_B3 | FEATURE_COPROC_B4; + break; + case llvm::ARM::ArchKind::ARMV8A: + case llvm::ARM::ArchKind::ARMV8R: + case llvm::ARM::ArchKind::ARMV8_1A: + case llvm::ARM::ArchKind::ARMV8_2A: + case llvm::ARM::ArchKind::ARMV8_3A: + case llvm::ARM::ArchKind::ARMV8_4A: + case llvm::ARM::ArchKind::ARMV8_5A: + case llvm::ARM::ArchKind::ARMV8_6A: + case llvm::ARM::ArchKind::ARMV8_7A: + case llvm::ARM::ArchKind::ARMV8_8A: + case llvm::ARM::ArchKind::ARMV8_9A: + case llvm::ARM::ArchKind::ARMV9A: + case llvm::ARM::ArchKind::ARMV9_1A: + case llvm::ARM::ArchKind::ARMV9_2A: + case llvm::ARM::ArchKind::ARMV9_3A: + case llvm::ARM::ArchKind::ARMV9_4A: + case llvm::ARM::ArchKind::ARMV9_5A: + // Filter __arm_cdp, __arm_ldcl, __arm_stcl in arm_acle.h + FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B3; + break; + case llvm::ARM::ArchKind::ARMV8MMainline: + case llvm::ARM::ArchKind::ARMV8_1MMainline: + FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | + FEATURE_COPROC_B3 | FEATURE_COPROC_B4; + break; + } + Builder.defineMacro("__ARM_FEATURE_COPROC", + "0x" + Twine::utohexstr(FeatureCoprocBF)); + if (ArchKind == llvm::ARM::ArchKind::XSCALE) Builder.defineMacro("__XSCALE__"); @@ -858,12 +1017,28 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, if (HasMatMul) Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1"); + if (HasPAC) + Builder.defineMacro("__ARM_FEATURE_PAUTH", "1"); + + if (HasBTI) + Builder.defineMacro("__ARM_FEATURE_BTI", "1"); + if (HasBFloat16) { Builder.defineMacro("__ARM_FEATURE_BF16", "1"); Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1"); Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1"); } + if (Opts.BranchTargetEnforcement) + Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1"); + + if (Opts.hasSignReturnAddress()) { + unsigned Value = 1; + if (Opts.isSignReturnAddressScopeAll()) + Value |= 1 << 2; + Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value)); + } + switch (ArchKind) { default: break; @@ -877,32 +1052,45 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, case llvm::ARM::ArchKind::ARMV8_4A: case llvm::ARM::ArchKind::ARMV8_5A: case llvm::ARM::ArchKind::ARMV8_6A: + case llvm::ARM::ArchKind::ARMV8_7A: + case llvm::ARM::ArchKind::ARMV8_8A: + case llvm::ARM::ArchKind::ARMV8_9A: + case llvm::ARM::ArchKind::ARMV9A: + case llvm::ARM::ArchKind::ARMV9_1A: + case llvm::ARM::ArchKind::ARMV9_2A: + case llvm::ARM::ArchKind::ARMV9_3A: + case llvm::ARM::ArchKind::ARMV9_4A: + case llvm::ARM::ArchKind::ARMV9_5A: getTargetDefinesARMV83A(Opts, Builder); break; } } -const Builtin::Info ARMTargetInfo::BuiltinInfo[] = { +static constexpr Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsNEON.def" #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ - {#ID, TYPE, ATTRS, nullptr, LANG, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG}, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ - {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, #include "clang/Basic/BuiltinsARM.def" }; ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin - - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfo, + clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin); } bool ARMTargetInfo::isCLZForZeroUndef() const { return false; } @@ -933,7 +1121,7 @@ const char *const ARMTargetInfo::GCCRegNames[] = { "q12", "q13", "q14", "q15"}; ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { @@ -946,7 +1134,7 @@ const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { }; ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const { - return llvm::makeArrayRef(GCCRegAliases); + return llvm::ArrayRef(GCCRegAliases); } bool ARMTargetInfo::validateAsmConstraint( @@ -968,6 +1156,8 @@ bool ARMTargetInfo::validateAsmConstraint( case 't': // s0-s31, d0-d31, or q0-q15 case 'w': // s0-s15, d0-d7, or q0-q3 case 'x': // s0-s31, d0-d15, or q0-q7 + if (FPRegsDisabled) + return false; Info.setAllowsRegister(); return true; case 'j': // An immediate integer between 0 and 65535 (valid for MOVW) @@ -1108,8 +1298,7 @@ bool ARMTargetInfo::validateConstraintModifier( bool isInOut = (Constraint[0] == '+'); // Strip off constraint modifiers. - while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') - Constraint = Constraint.substr(1); + Constraint = Constraint.ltrim("=+&"); switch (Constraint[0]) { default: @@ -1127,7 +1316,7 @@ bool ARMTargetInfo::validateConstraintModifier( return true; } -const char *ARMTargetInfo::getClobbers() const { +std::string_view ARMTargetInfo::getClobbers() const { // FIXME: Is this really right? return ""; } @@ -1289,11 +1478,6 @@ DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) { HasAlignMac68kSupport = true; - // iOS always has 64-bit atomic instructions. - // FIXME: This should be based off of the target features in - // ARMleTargetInfo. - MaxAtomicInlineWidth = 64; - if (Triple.isWatchABI()) { // Darwin on iOS uses a variant of the ARM C++ ABI. TheCXXABI.set(TargetCXXABI::WatchOS); diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h index 0910064a033b..9802eb01abf3 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h @@ -16,9 +16,10 @@ #include "OSTargets.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/TargetParser.h" +#include "llvm/TargetParser/ARMTargetParser.h" +#include "llvm/TargetParser/ARMTargetParserCommon.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { @@ -78,6 +79,9 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { unsigned Unaligned : 1; unsigned DotProd : 1; unsigned HasMatMul : 1; + unsigned FPRegsDisabled : 1; + unsigned HasPAC : 1; + unsigned HasBTI : 1; enum { LDREX_B = (1 << 0), /// byte (8-bit) @@ -96,7 +100,18 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { }; uint32_t HW_FP; - static const Builtin::Info BuiltinInfo[]; + enum { + /// __arm_cdp __arm_ldc, __arm_ldcl, __arm_stc, + /// __arm_stcl, __arm_mcr and __arm_mrc + FEATURE_COPROC_B1 = (1 << 0), + /// __arm_cdp2, __arm_ldc2, __arm_stc2, __arm_ldc2l, + /// __arm_stc2l, __arm_mcr2 and __arm_mrc2 + FEATURE_COPROC_B2 = (1 << 1), + /// __arm_mcrr, __arm_mrrc + FEATURE_COPROC_B3 = (1 << 2), + /// __arm_mcrr2, __arm_mrrc2 + FEATURE_COPROC_B4 = (1 << 3), + }; void setABIAAPCS(); void setABIAPCS(bool IsAAPCS16); @@ -122,6 +137,11 @@ public: StringRef getABI() const override; bool setABI(const std::string &Name) override; + bool isBranchProtectionSupportedArch(StringRef Arch) const override; + bool validateBranchProtection(StringRef Spec, StringRef Arch, + BranchProtectionInfo &BPI, + StringRef &Err) const override; + // FIXME: This should be based on Arch attributes, not CPU names. bool initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, @@ -174,7 +194,7 @@ public: bool validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size, std::string &SuggestedModifier) const override; - const char *getClobbers() const override; + std::string_view getClobbers() const override; StringRef getConstraintRegister(StringRef Constraint, StringRef Expression) const override { @@ -187,8 +207,8 @@ public: bool hasSjLjLowering() const override; - bool hasExtIntType() const override { return true; } - + bool hasBitIntType() const override { return true; } + const char *getBFloat16Mangling() const override { return "u6__bf16"; }; }; diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp index e87b7338c4d6..85ca4bc30c46 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp @@ -24,297 +24,475 @@ namespace targets { struct LLVM_LIBRARY_VISIBILITY MCUInfo { const char *Name; const char *DefineName; + StringRef Arch; // The __AVR_ARCH__ value. + const int NumFlashBanks; // Set to 0 for the devices do not support LPM/ELPM. }; -// This list should be kept up-to-date with AVRDevices.td in LLVM. +// NOTE: This list has been synchronized with gcc-avr 5.4.0 and avr-libc 2.0.0. static MCUInfo AVRMcus[] = { - {"at90s1200", "__AVR_AT90S1200__"}, - {"attiny11", "__AVR_ATtiny11__"}, - {"attiny12", "__AVR_ATtiny12__"}, - {"attiny15", "__AVR_ATtiny15__"}, - {"attiny28", "__AVR_ATtiny28__"}, - {"at90s2313", "__AVR_AT90S2313__"}, - {"at90s2323", "__AVR_AT90S2323__"}, - {"at90s2333", "__AVR_AT90S2333__"}, - {"at90s2343", "__AVR_AT90S2343__"}, - {"attiny22", "__AVR_ATtiny22__"}, - {"attiny26", "__AVR_ATtiny26__"}, - {"at86rf401", "__AVR_AT86RF401__"}, - {"at90s4414", "__AVR_AT90S4414__"}, - {"at90s4433", "__AVR_AT90S4433__"}, - {"at90s4434", "__AVR_AT90S4434__"}, - {"at90s8515", "__AVR_AT90S8515__"}, - {"at90c8534", "__AVR_AT90c8534__"}, - {"at90s8535", "__AVR_AT90S8535__"}, - {"ata5272", "__AVR_ATA5272__"}, - {"attiny13", "__AVR_ATtiny13__"}, - {"attiny13a", "__AVR_ATtiny13A__"}, - {"attiny2313", "__AVR_ATtiny2313__"}, - {"attiny2313a", "__AVR_ATtiny2313A__"}, - {"attiny24", "__AVR_ATtiny24__"}, - {"attiny24a", "__AVR_ATtiny24A__"}, - {"attiny4313", "__AVR_ATtiny4313__"}, - {"attiny44", "__AVR_ATtiny44__"}, - {"attiny44a", "__AVR_ATtiny44A__"}, - {"attiny84", "__AVR_ATtiny84__"}, - {"attiny84a", "__AVR_ATtiny84A__"}, - {"attiny25", "__AVR_ATtiny25__"}, - {"attiny45", "__AVR_ATtiny45__"}, - {"attiny85", "__AVR_ATtiny85__"}, - {"attiny261", "__AVR_ATtiny261__"}, - {"attiny261a", "__AVR_ATtiny261A__"}, - {"attiny441", "__AVR_ATtiny441__"}, - {"attiny461", "__AVR_ATtiny461__"}, - {"attiny461a", "__AVR_ATtiny461A__"}, - {"attiny841", "__AVR_ATtiny841__"}, - {"attiny861", "__AVR_ATtiny861__"}, - {"attiny861a", "__AVR_ATtiny861A__"}, - {"attiny87", "__AVR_ATtiny87__"}, - {"attiny43u", "__AVR_ATtiny43U__"}, - {"attiny48", "__AVR_ATtiny48__"}, - {"attiny88", "__AVR_ATtiny88__"}, - {"attiny828", "__AVR_ATtiny828__"}, - {"at43usb355", "__AVR_AT43USB355__"}, - {"at76c711", "__AVR_AT76C711__"}, - {"atmega103", "__AVR_ATmega103__"}, - {"at43usb320", "__AVR_AT43USB320__"}, - {"attiny167", "__AVR_ATtiny167__"}, - {"at90usb82", "__AVR_AT90USB82__"}, - {"at90usb162", "__AVR_AT90USB162__"}, - {"ata5505", "__AVR_ATA5505__"}, - {"atmega8u2", "__AVR_ATmega8U2__"}, - {"atmega16u2", "__AVR_ATmega16U2__"}, - {"atmega32u2", "__AVR_ATmega32U2__"}, - {"attiny1634", "__AVR_ATtiny1634__"}, - {"atmega8", "__AVR_ATmega8__"}, - {"ata6289", "__AVR_ATA6289__"}, - {"atmega8a", "__AVR_ATmega8A__"}, - {"ata6285", "__AVR_ATA6285__"}, - {"ata6286", "__AVR_ATA6286__"}, - {"atmega48", "__AVR_ATmega48__"}, - {"atmega48a", "__AVR_ATmega48A__"}, - {"atmega48pa", "__AVR_ATmega48PA__"}, - {"atmega48pb", "__AVR_ATmega48PB__"}, - {"atmega48p", "__AVR_ATmega48P__"}, - {"atmega88", "__AVR_ATmega88__"}, - {"atmega88a", "__AVR_ATmega88A__"}, - {"atmega88p", "__AVR_ATmega88P__"}, - {"atmega88pa", "__AVR_ATmega88PA__"}, - {"atmega88pb", "__AVR_ATmega88PB__"}, - {"atmega8515", "__AVR_ATmega8515__"}, - {"atmega8535", "__AVR_ATmega8535__"}, - {"atmega8hva", "__AVR_ATmega8HVA__"}, - {"at90pwm1", "__AVR_AT90PWM1__"}, - {"at90pwm2", "__AVR_AT90PWM2__"}, - {"at90pwm2b", "__AVR_AT90PWM2B__"}, - {"at90pwm3", "__AVR_AT90PWM3__"}, - {"at90pwm3b", "__AVR_AT90PWM3B__"}, - {"at90pwm81", "__AVR_AT90PWM81__"}, - {"ata5790", "__AVR_ATA5790__"}, - {"ata5795", "__AVR_ATA5795__"}, - {"atmega16", "__AVR_ATmega16__"}, - {"atmega16a", "__AVR_ATmega16A__"}, - {"atmega161", "__AVR_ATmega161__"}, - {"atmega162", "__AVR_ATmega162__"}, - {"atmega163", "__AVR_ATmega163__"}, - {"atmega164a", "__AVR_ATmega164A__"}, - {"atmega164p", "__AVR_ATmega164P__"}, - {"atmega164pa", "__AVR_ATmega164PA__"}, - {"atmega165", "__AVR_ATmega165__"}, - {"atmega165a", "__AVR_ATmega165A__"}, - {"atmega165p", "__AVR_ATmega165P__"}, - {"atmega165pa", "__AVR_ATmega165PA__"}, - {"atmega168", "__AVR_ATmega168__"}, - {"atmega168a", "__AVR_ATmega168A__"}, - {"atmega168p", "__AVR_ATmega168P__"}, - {"atmega168pa", "__AVR_ATmega168PA__"}, - {"atmega168pb", "__AVR_ATmega168PB__"}, - {"atmega169", "__AVR_ATmega169__"}, - {"atmega169a", "__AVR_ATmega169A__"}, - {"atmega169p", "__AVR_ATmega169P__"}, - {"atmega169pa", "__AVR_ATmega169PA__"}, - {"atmega32", "__AVR_ATmega32__"}, - {"atmega32a", "__AVR_ATmega32A__"}, - {"atmega323", "__AVR_ATmega323__"}, - {"atmega324a", "__AVR_ATmega324A__"}, - {"atmega324p", "__AVR_ATmega324P__"}, - {"atmega324pa", "__AVR_ATmega324PA__"}, - {"atmega324pb", "__AVR_ATmega324PB__"}, - {"atmega325", "__AVR_ATmega325__"}, - {"atmega325a", "__AVR_ATmega325A__"}, - {"atmega325p", "__AVR_ATmega325P__"}, - {"atmega325pa", "__AVR_ATmega325PA__"}, - {"atmega3250", "__AVR_ATmega3250__"}, - {"atmega3250a", "__AVR_ATmega3250A__"}, - {"atmega3250p", "__AVR_ATmega3250P__"}, - {"atmega3250pa", "__AVR_ATmega3250PA__"}, - {"atmega328", "__AVR_ATmega328__"}, - {"atmega328p", "__AVR_ATmega328P__"}, - {"atmega328pb", "__AVR_ATmega328PB__"}, - {"atmega329", "__AVR_ATmega329__"}, - {"atmega329a", "__AVR_ATmega329A__"}, - {"atmega329p", "__AVR_ATmega329P__"}, - {"atmega329pa", "__AVR_ATmega329PA__"}, - {"atmega3290", "__AVR_ATmega3290__"}, - {"atmega3290a", "__AVR_ATmega3290A__"}, - {"atmega3290p", "__AVR_ATmega3290P__"}, - {"atmega3290pa", "__AVR_ATmega3290PA__"}, - {"atmega406", "__AVR_ATmega406__"}, - {"atmega64", "__AVR_ATmega64__"}, - {"atmega64a", "__AVR_ATmega64A__"}, - {"atmega640", "__AVR_ATmega640__"}, - {"atmega644", "__AVR_ATmega644__"}, - {"atmega644a", "__AVR_ATmega644A__"}, - {"atmega644p", "__AVR_ATmega644P__"}, - {"atmega644pa", "__AVR_ATmega644PA__"}, - {"atmega645", "__AVR_ATmega645__"}, - {"atmega645a", "__AVR_ATmega645A__"}, - {"atmega645p", "__AVR_ATmega645P__"}, - {"atmega649", "__AVR_ATmega649__"}, - {"atmega649a", "__AVR_ATmega649A__"}, - {"atmega649p", "__AVR_ATmega649P__"}, - {"atmega6450", "__AVR_ATmega6450__"}, - {"atmega6450a", "__AVR_ATmega6450A__"}, - {"atmega6450p", "__AVR_ATmega6450P__"}, - {"atmega6490", "__AVR_ATmega6490__"}, - {"atmega6490a", "__AVR_ATmega6490A__"}, - {"atmega6490p", "__AVR_ATmega6490P__"}, - {"atmega64rfr2", "__AVR_ATmega64RFR2__"}, - {"atmega644rfr2", "__AVR_ATmega644RFR2__"}, - {"atmega16hva", "__AVR_ATmega16HVA__"}, - {"atmega16hva2", "__AVR_ATmega16HVA2__"}, - {"atmega16hvb", "__AVR_ATmega16HVB__"}, - {"atmega16hvbrevb", "__AVR_ATmega16HVBREVB__"}, - {"atmega32hvb", "__AVR_ATmega32HVB__"}, - {"atmega32hvbrevb", "__AVR_ATmega32HVBREVB__"}, - {"atmega64hve", "__AVR_ATmega64HVE__"}, - {"at90can32", "__AVR_AT90CAN32__"}, - {"at90can64", "__AVR_AT90CAN64__"}, - {"at90pwm161", "__AVR_AT90PWM161__"}, - {"at90pwm216", "__AVR_AT90PWM216__"}, - {"at90pwm316", "__AVR_AT90PWM316__"}, - {"atmega32c1", "__AVR_ATmega32C1__"}, - {"atmega64c1", "__AVR_ATmega64C1__"}, - {"atmega16m1", "__AVR_ATmega16M1__"}, - {"atmega32m1", "__AVR_ATmega32M1__"}, - {"atmega64m1", "__AVR_ATmega64M1__"}, - {"atmega16u4", "__AVR_ATmega16U4__"}, - {"atmega32u4", "__AVR_ATmega32U4__"}, - {"atmega32u6", "__AVR_ATmega32U6__"}, - {"at90usb646", "__AVR_AT90USB646__"}, - {"at90usb647", "__AVR_AT90USB647__"}, - {"at90scr100", "__AVR_AT90SCR100__"}, - {"at94k", "__AVR_AT94K__"}, - {"m3000", "__AVR_AT000__"}, - {"atmega128", "__AVR_ATmega128__"}, - {"atmega128a", "__AVR_ATmega128A__"}, - {"atmega1280", "__AVR_ATmega1280__"}, - {"atmega1281", "__AVR_ATmega1281__"}, - {"atmega1284", "__AVR_ATmega1284__"}, - {"atmega1284p", "__AVR_ATmega1284P__"}, - {"atmega128rfa1", "__AVR_ATmega128RFA1__"}, - {"atmega128rfr2", "__AVR_ATmega128RFR2__"}, - {"atmega1284rfr2", "__AVR_ATmega1284RFR2__"}, - {"at90can128", "__AVR_AT90CAN128__"}, - {"at90usb1286", "__AVR_AT90USB1286__"}, - {"at90usb1287", "__AVR_AT90USB1287__"}, - {"atmega2560", "__AVR_ATmega2560__"}, - {"atmega2561", "__AVR_ATmega2561__"}, - {"atmega256rfr2", "__AVR_ATmega256RFR2__"}, - {"atmega2564rfr2", "__AVR_ATmega2564RFR2__"}, - {"atxmega16a4", "__AVR_ATxmega16A4__"}, - {"atxmega16a4u", "__AVR_ATxmega16a4U__"}, - {"atxmega16c4", "__AVR_ATxmega16C4__"}, - {"atxmega16d4", "__AVR_ATxmega16D4__"}, - {"atxmega32a4", "__AVR_ATxmega32A4__"}, - {"atxmega32a4u", "__AVR_ATxmega32A4U__"}, - {"atxmega32c4", "__AVR_ATxmega32C4__"}, - {"atxmega32d4", "__AVR_ATxmega32D4__"}, - {"atxmega32e5", "__AVR_ATxmega32E5__"}, - {"atxmega16e5", "__AVR_ATxmega16E5__"}, - {"atxmega8e5", "__AVR_ATxmega8E5__"}, - {"atxmega32x1", "__AVR_ATxmega32X1__"}, - {"atxmega64a3", "__AVR_ATxmega64A3__"}, - {"atxmega64a3u", "__AVR_ATxmega64A3U__"}, - {"atxmega64a4u", "__AVR_ATxmega64A4U__"}, - {"atxmega64b1", "__AVR_ATxmega64B1__"}, - {"atxmega64b3", "__AVR_ATxmega64B3__"}, - {"atxmega64c3", "__AVR_ATxmega64C3__"}, - {"atxmega64d3", "__AVR_ATxmega64D3__"}, - {"atxmega64d4", "__AVR_ATxmega64D4__"}, - {"atxmega64a1", "__AVR_ATxmega64A1__"}, - {"atxmega64a1u", "__AVR_ATxmega64A1U__"}, - {"atxmega128a3", "__AVR_ATxmega128A3__"}, - {"atxmega128a3u", "__AVR_ATxmega128A3U__"}, - {"atxmega128b1", "__AVR_ATxmega128B1__"}, - {"atxmega128b3", "__AVR_ATxmega128B3__"}, - {"atxmega128c3", "__AVR_ATxmega128C3__"}, - {"atxmega128d3", "__AVR_ATxmega128D3__"}, - {"atxmega128d4", "__AVR_ATxmega128D4__"}, - {"atxmega192a3", "__AVR_ATxmega192A3__"}, - {"atxmega192a3u", "__AVR_ATxmega192A3U__"}, - {"atxmega192c3", "__AVR_ATxmega192C3__"}, - {"atxmega192d3", "__AVR_ATxmega192D3__"}, - {"atxmega256a3", "__AVR_ATxmega256A3__"}, - {"atxmega256a3u", "__AVR_ATxmega256A3U__"}, - {"atxmega256a3b", "__AVR_ATxmega256A3B__"}, - {"atxmega256a3bu", "__AVR_ATxmega256A3BU__"}, - {"atxmega256c3", "__AVR_ATxmega256C3__"}, - {"atxmega256d3", "__AVR_ATxmega256D3__"}, - {"atxmega384c3", "__AVR_ATxmega384C3__"}, - {"atxmega384d3", "__AVR_ATxmega384D3__"}, - {"atxmega128a1", "__AVR_ATxmega128A1__"}, - {"atxmega128a1u", "__AVR_ATxmega128A1U__"}, - {"atxmega128a4u", "__AVR_ATxmega128a4U__"}, - {"attiny4", "__AVR_ATtiny4__"}, - {"attiny5", "__AVR_ATtiny5__"}, - {"attiny9", "__AVR_ATtiny9__"}, - {"attiny10", "__AVR_ATtiny10__"}, - {"attiny20", "__AVR_ATtiny20__"}, - {"attiny40", "__AVR_ATtiny40__"}, - {"attiny102", "__AVR_ATtiny102__"}, - {"attiny104", "__AVR_ATtiny104__"}, + {"avr1", NULL, "1", 0}, + {"at90s1200", "__AVR_AT90S1200__", "1", 0}, + {"attiny11", "__AVR_ATtiny11__", "1", 0}, + {"attiny12", "__AVR_ATtiny12__", "1", 0}, + {"attiny15", "__AVR_ATtiny15__", "1", 0}, + {"attiny28", "__AVR_ATtiny28__", "1", 0}, + {"avr2", NULL, "2", 1}, + {"at90s2313", "__AVR_AT90S2313__", "2", 1}, + {"at90s2323", "__AVR_AT90S2323__", "2", 1}, + {"at90s2333", "__AVR_AT90S2333__", "2", 1}, + {"at90s2343", "__AVR_AT90S2343__", "2", 1}, + {"attiny22", "__AVR_ATtiny22__", "2", 1}, + {"attiny26", "__AVR_ATtiny26__", "2", 1}, + {"at86rf401", "__AVR_AT86RF401__", "25", 1}, + {"at90s4414", "__AVR_AT90S4414__", "2", 1}, + {"at90s4433", "__AVR_AT90S4433__", "2", 1}, + {"at90s4434", "__AVR_AT90S4434__", "2", 1}, + {"at90s8515", "__AVR_AT90S8515__", "2", 1}, + {"at90c8534", "__AVR_AT90c8534__", "2", 1}, + {"at90s8535", "__AVR_AT90S8535__", "2", 1}, + {"avr25", NULL, "25", 1}, + {"ata5272", "__AVR_ATA5272__", "25", 1}, + {"ata6616c", "__AVR_ATA6616c__", "25", 1}, + {"attiny13", "__AVR_ATtiny13__", "25", 1}, + {"attiny13a", "__AVR_ATtiny13A__", "25", 1}, + {"attiny2313", "__AVR_ATtiny2313__", "25", 1}, + {"attiny2313a", "__AVR_ATtiny2313A__", "25", 1}, + {"attiny24", "__AVR_ATtiny24__", "25", 1}, + {"attiny24a", "__AVR_ATtiny24A__", "25", 1}, + {"attiny4313", "__AVR_ATtiny4313__", "25", 1}, + {"attiny44", "__AVR_ATtiny44__", "25", 1}, + {"attiny44a", "__AVR_ATtiny44A__", "25", 1}, + {"attiny84", "__AVR_ATtiny84__", "25", 1}, + {"attiny84a", "__AVR_ATtiny84A__", "25", 1}, + {"attiny25", "__AVR_ATtiny25__", "25", 1}, + {"attiny45", "__AVR_ATtiny45__", "25", 1}, + {"attiny85", "__AVR_ATtiny85__", "25", 1}, + {"attiny261", "__AVR_ATtiny261__", "25", 1}, + {"attiny261a", "__AVR_ATtiny261A__", "25", 1}, + {"attiny441", "__AVR_ATtiny441__", "25", 1}, + {"attiny461", "__AVR_ATtiny461__", "25", 1}, + {"attiny461a", "__AVR_ATtiny461A__", "25", 1}, + {"attiny841", "__AVR_ATtiny841__", "25", 1}, + {"attiny861", "__AVR_ATtiny861__", "25", 1}, + {"attiny861a", "__AVR_ATtiny861A__", "25", 1}, + {"attiny87", "__AVR_ATtiny87__", "25", 1}, + {"attiny43u", "__AVR_ATtiny43U__", "25", 1}, + {"attiny48", "__AVR_ATtiny48__", "25", 1}, + {"attiny88", "__AVR_ATtiny88__", "25", 1}, + {"attiny828", "__AVR_ATtiny828__", "25", 1}, + {"avr3", NULL, "3", 1}, + {"at43usb355", "__AVR_AT43USB355__", "3", 1}, + {"at76c711", "__AVR_AT76C711__", "3", 1}, + {"avr31", NULL, "31", 1}, + {"atmega103", "__AVR_ATmega103__", "31", 1}, + {"at43usb320", "__AVR_AT43USB320__", "31", 1}, + {"avr35", NULL, "35", 1}, + {"attiny167", "__AVR_ATtiny167__", "35", 1}, + {"at90usb82", "__AVR_AT90USB82__", "35", 1}, + {"at90usb162", "__AVR_AT90USB162__", "35", 1}, + {"ata5505", "__AVR_ATA5505__", "35", 1}, + {"ata6617c", "__AVR_ATA6617C__", "35", 1}, + {"ata664251", "__AVR_ATA664251__", "35", 1}, + {"atmega8u2", "__AVR_ATmega8U2__", "35", 1}, + {"atmega16u2", "__AVR_ATmega16U2__", "35", 1}, + {"atmega32u2", "__AVR_ATmega32U2__", "35", 1}, + {"attiny1634", "__AVR_ATtiny1634__", "35", 1}, + {"avr4", NULL, "4", 1}, + {"atmega8", "__AVR_ATmega8__", "4", 1}, + {"ata6289", "__AVR_ATA6289__", "4", 1}, + {"atmega8a", "__AVR_ATmega8A__", "4", 1}, + {"ata6285", "__AVR_ATA6285__", "4", 1}, + {"ata6286", "__AVR_ATA6286__", "4", 1}, + {"ata6612c", "__AVR_ATA6612C__", "4", 1}, + {"atmega48", "__AVR_ATmega48__", "4", 1}, + {"atmega48a", "__AVR_ATmega48A__", "4", 1}, + {"atmega48pa", "__AVR_ATmega48PA__", "4", 1}, + {"atmega48pb", "__AVR_ATmega48PB__", "4", 1}, + {"atmega48p", "__AVR_ATmega48P__", "4", 1}, + {"atmega88", "__AVR_ATmega88__", "4", 1}, + {"atmega88a", "__AVR_ATmega88A__", "4", 1}, + {"atmega88p", "__AVR_ATmega88P__", "4", 1}, + {"atmega88pa", "__AVR_ATmega88PA__", "4", 1}, + {"atmega88pb", "__AVR_ATmega88PB__", "4", 1}, + {"atmega8515", "__AVR_ATmega8515__", "4", 1}, + {"atmega8535", "__AVR_ATmega8535__", "4", 1}, + {"atmega8hva", "__AVR_ATmega8HVA__", "4", 1}, + {"at90pwm1", "__AVR_AT90PWM1__", "4", 1}, + {"at90pwm2", "__AVR_AT90PWM2__", "4", 1}, + {"at90pwm2b", "__AVR_AT90PWM2B__", "4", 1}, + {"at90pwm3", "__AVR_AT90PWM3__", "4", 1}, + {"at90pwm3b", "__AVR_AT90PWM3B__", "4", 1}, + {"at90pwm81", "__AVR_AT90PWM81__", "4", 1}, + {"avr5", NULL, "5", 1}, + {"ata5702m322", "__AVR_ATA5702M322__", "5", 1}, + {"ata5782", "__AVR_ATA5782__", "5", 1}, + {"ata5790", "__AVR_ATA5790__", "5", 1}, + {"ata5790n", "__AVR_ATA5790N__", "5", 1}, + {"ata5791", "__AVR_ATA5791__", "5", 1}, + {"ata5795", "__AVR_ATA5795__", "5", 1}, + {"ata5831", "__AVR_ATA5831__", "5", 1}, + {"ata6613c", "__AVR_ATA6613C__", "5", 1}, + {"ata6614q", "__AVR_ATA6614Q__", "5", 1}, + {"ata8210", "__AVR_ATA8210__", "5", 1}, + {"ata8510", "__AVR_ATA8510__", "5", 1}, + {"atmega16", "__AVR_ATmega16__", "5", 1}, + {"atmega16a", "__AVR_ATmega16A__", "5", 1}, + {"atmega161", "__AVR_ATmega161__", "5", 1}, + {"atmega162", "__AVR_ATmega162__", "5", 1}, + {"atmega163", "__AVR_ATmega163__", "5", 1}, + {"atmega164a", "__AVR_ATmega164A__", "5", 1}, + {"atmega164p", "__AVR_ATmega164P__", "5", 1}, + {"atmega164pa", "__AVR_ATmega164PA__", "5", 1}, + {"atmega165", "__AVR_ATmega165__", "5", 1}, + {"atmega165a", "__AVR_ATmega165A__", "5", 1}, + {"atmega165p", "__AVR_ATmega165P__", "5", 1}, + {"atmega165pa", "__AVR_ATmega165PA__", "5", 1}, + {"atmega168", "__AVR_ATmega168__", "5", 1}, + {"atmega168a", "__AVR_ATmega168A__", "5", 1}, + {"atmega168p", "__AVR_ATmega168P__", "5", 1}, + {"atmega168pa", "__AVR_ATmega168PA__", "5", 1}, + {"atmega168pb", "__AVR_ATmega168PB__", "5", 1}, + {"atmega169", "__AVR_ATmega169__", "5", 1}, + {"atmega169a", "__AVR_ATmega169A__", "5", 1}, + {"atmega169p", "__AVR_ATmega169P__", "5", 1}, + {"atmega169pa", "__AVR_ATmega169PA__", "5", 1}, + {"atmega32", "__AVR_ATmega32__", "5", 1}, + {"atmega32a", "__AVR_ATmega32A__", "5", 1}, + {"atmega323", "__AVR_ATmega323__", "5", 1}, + {"atmega324a", "__AVR_ATmega324A__", "5", 1}, + {"atmega324p", "__AVR_ATmega324P__", "5", 1}, + {"atmega324pa", "__AVR_ATmega324PA__", "5", 1}, + {"atmega324pb", "__AVR_ATmega324PB__", "5", 1}, + {"atmega325", "__AVR_ATmega325__", "5", 1}, + {"atmega325a", "__AVR_ATmega325A__", "5", 1}, + {"atmega325p", "__AVR_ATmega325P__", "5", 1}, + {"atmega325pa", "__AVR_ATmega325PA__", "5", 1}, + {"atmega3250", "__AVR_ATmega3250__", "5", 1}, + {"atmega3250a", "__AVR_ATmega3250A__", "5", 1}, + {"atmega3250p", "__AVR_ATmega3250P__", "5", 1}, + {"atmega3250pa", "__AVR_ATmega3250PA__", "5", 1}, + {"atmega328", "__AVR_ATmega328__", "5", 1}, + {"atmega328p", "__AVR_ATmega328P__", "5", 1}, + {"atmega328pb", "__AVR_ATmega328PB__", "5", 1}, + {"atmega329", "__AVR_ATmega329__", "5", 1}, + {"atmega329a", "__AVR_ATmega329A__", "5", 1}, + {"atmega329p", "__AVR_ATmega329P__", "5", 1}, + {"atmega329pa", "__AVR_ATmega329PA__", "5", 1}, + {"atmega3290", "__AVR_ATmega3290__", "5", 1}, + {"atmega3290a", "__AVR_ATmega3290A__", "5", 1}, + {"atmega3290p", "__AVR_ATmega3290P__", "5", 1}, + {"atmega3290pa", "__AVR_ATmega3290PA__", "5", 1}, + {"atmega406", "__AVR_ATmega406__", "5", 1}, + {"atmega64", "__AVR_ATmega64__", "5", 1}, + {"atmega64a", "__AVR_ATmega64A__", "5", 1}, + {"atmega640", "__AVR_ATmega640__", "5", 1}, + {"atmega644", "__AVR_ATmega644__", "5", 1}, + {"atmega644a", "__AVR_ATmega644A__", "5", 1}, + {"atmega644p", "__AVR_ATmega644P__", "5", 1}, + {"atmega644pa", "__AVR_ATmega644PA__", "5", 1}, + {"atmega645", "__AVR_ATmega645__", "5", 1}, + {"atmega645a", "__AVR_ATmega645A__", "5", 1}, + {"atmega645p", "__AVR_ATmega645P__", "5", 1}, + {"atmega649", "__AVR_ATmega649__", "5", 1}, + {"atmega649a", "__AVR_ATmega649A__", "5", 1}, + {"atmega649p", "__AVR_ATmega649P__", "5", 1}, + {"atmega6450", "__AVR_ATmega6450__", "5", 1}, + {"atmega6450a", "__AVR_ATmega6450A__", "5", 1}, + {"atmega6450p", "__AVR_ATmega6450P__", "5", 1}, + {"atmega6490", "__AVR_ATmega6490__", "5", 1}, + {"atmega6490a", "__AVR_ATmega6490A__", "5", 1}, + {"atmega6490p", "__AVR_ATmega6490P__", "5", 1}, + {"atmega64rfr2", "__AVR_ATmega64RFR2__", "5", 1}, + {"atmega644rfr2", "__AVR_ATmega644RFR2__", "5", 1}, + {"atmega16hva", "__AVR_ATmega16HVA__", "5", 1}, + {"atmega16hva2", "__AVR_ATmega16HVA2__", "5", 1}, + {"atmega16hvb", "__AVR_ATmega16HVB__", "5", 1}, + {"atmega16hvbrevb", "__AVR_ATmega16HVBREVB__", "5", 1}, + {"atmega32hvb", "__AVR_ATmega32HVB__", "5", 1}, + {"atmega32hvbrevb", "__AVR_ATmega32HVBREVB__", "5", 1}, + {"atmega64hve", "__AVR_ATmega64HVE__", "5", 1}, + {"atmega64hve2", "__AVR_ATmega64HVE2__", "5", 1}, + {"at90can32", "__AVR_AT90CAN32__", "5", 1}, + {"at90can64", "__AVR_AT90CAN64__", "5", 1}, + {"at90pwm161", "__AVR_AT90PWM161__", "5", 1}, + {"at90pwm216", "__AVR_AT90PWM216__", "5", 1}, + {"at90pwm316", "__AVR_AT90PWM316__", "5", 1}, + {"atmega32c1", "__AVR_ATmega32C1__", "5", 1}, + {"atmega64c1", "__AVR_ATmega64C1__", "5", 1}, + {"atmega16m1", "__AVR_ATmega16M1__", "5", 1}, + {"atmega32m1", "__AVR_ATmega32M1__", "5", 1}, + {"atmega64m1", "__AVR_ATmega64M1__", "5", 1}, + {"atmega16u4", "__AVR_ATmega16U4__", "5", 1}, + {"atmega32u4", "__AVR_ATmega32U4__", "5", 1}, + {"atmega32u6", "__AVR_ATmega32U6__", "5", 1}, + {"at90usb646", "__AVR_AT90USB646__", "5", 1}, + {"at90usb647", "__AVR_AT90USB647__", "5", 1}, + {"at90scr100", "__AVR_AT90SCR100__", "5", 1}, + {"at94k", "__AVR_AT94K__", "5", 1}, + {"m3000", "__AVR_AT000__", "5", 1}, + {"avr51", NULL, "51", 2}, + {"atmega128", "__AVR_ATmega128__", "51", 2}, + {"atmega128a", "__AVR_ATmega128A__", "51", 2}, + {"atmega1280", "__AVR_ATmega1280__", "51", 2}, + {"atmega1281", "__AVR_ATmega1281__", "51", 2}, + {"atmega1284", "__AVR_ATmega1284__", "51", 2}, + {"atmega1284p", "__AVR_ATmega1284P__", "51", 2}, + {"atmega128rfa1", "__AVR_ATmega128RFA1__", "51", 2}, + {"atmega128rfr2", "__AVR_ATmega128RFR2__", "51", 2}, + {"atmega1284rfr2", "__AVR_ATmega1284RFR2__", "51", 2}, + {"at90can128", "__AVR_AT90CAN128__", "51", 2}, + {"at90usb1286", "__AVR_AT90USB1286__", "51", 2}, + {"at90usb1287", "__AVR_AT90USB1287__", "51", 2}, + {"avr6", NULL, "6", 4}, + {"atmega2560", "__AVR_ATmega2560__", "6", 4}, + {"atmega2561", "__AVR_ATmega2561__", "6", 4}, + {"atmega256rfr2", "__AVR_ATmega256RFR2__", "6", 4}, + {"atmega2564rfr2", "__AVR_ATmega2564RFR2__", "6", 4}, + {"avrxmega2", NULL, "102", 1}, + {"atxmega16a4", "__AVR_ATxmega16A4__", "102", 1}, + {"atxmega16a4u", "__AVR_ATxmega16A4U__", "102", 1}, + {"atxmega16c4", "__AVR_ATxmega16C4__", "102", 1}, + {"atxmega16d4", "__AVR_ATxmega16D4__", "102", 1}, + {"atxmega32a4", "__AVR_ATxmega32A4__", "102", 1}, + {"atxmega32a4u", "__AVR_ATxmega32A4U__", "102", 1}, + {"atxmega32c3", "__AVR_ATxmega32C3__", "102", 1}, + {"atxmega32c4", "__AVR_ATxmega32C4__", "102", 1}, + {"atxmega32d3", "__AVR_ATxmega32D3__", "102", 1}, + {"atxmega32d4", "__AVR_ATxmega32D4__", "102", 1}, + {"atxmega32e5", "__AVR_ATxmega32E5__", "102", 1}, + {"atxmega16e5", "__AVR_ATxmega16E5__", "102", 1}, + {"atxmega8e5", "__AVR_ATxmega8E5__", "102", 1}, + {"avrxmega4", NULL, "104", 1}, + {"atxmega64a3", "__AVR_ATxmega64A3__", "104", 1}, + {"atxmega64a3u", "__AVR_ATxmega64A3U__", "104", 1}, + {"atxmega64a4u", "__AVR_ATxmega64A4U__", "104", 1}, + {"atxmega64b1", "__AVR_ATxmega64B1__", "104", 1}, + {"atxmega64b3", "__AVR_ATxmega64B3__", "104", 1}, + {"atxmega64c3", "__AVR_ATxmega64C3__", "104", 1}, + {"atxmega64d3", "__AVR_ATxmega64D3__", "104", 1}, + {"atxmega64d4", "__AVR_ATxmega64D4__", "104", 1}, + {"avrxmega5", NULL, "105", 1}, + {"atxmega64a1", "__AVR_ATxmega64A1__", "105", 1}, + {"atxmega64a1u", "__AVR_ATxmega64A1U__", "105", 1}, + {"avrxmega6", NULL, "106", 6}, + {"atxmega128a3", "__AVR_ATxmega128A3__", "106", 2}, + {"atxmega128a3u", "__AVR_ATxmega128A3U__", "106", 2}, + {"atxmega128b1", "__AVR_ATxmega128B1__", "106", 2}, + {"atxmega128b3", "__AVR_ATxmega128B3__", "106", 2}, + {"atxmega128c3", "__AVR_ATxmega128C3__", "106", 2}, + {"atxmega128d3", "__AVR_ATxmega128D3__", "106", 2}, + {"atxmega128d4", "__AVR_ATxmega128D4__", "106", 2}, + {"atxmega192a3", "__AVR_ATxmega192A3__", "106", 3}, + {"atxmega192a3u", "__AVR_ATxmega192A3U__", "106", 3}, + {"atxmega192c3", "__AVR_ATxmega192C3__", "106", 3}, + {"atxmega192d3", "__AVR_ATxmega192D3__", "106", 3}, + {"atxmega256a3", "__AVR_ATxmega256A3__", "106", 4}, + {"atxmega256a3u", "__AVR_ATxmega256A3U__", "106", 4}, + {"atxmega256a3b", "__AVR_ATxmega256A3B__", "106", 4}, + {"atxmega256a3bu", "__AVR_ATxmega256A3BU__", "106", 4}, + {"atxmega256c3", "__AVR_ATxmega256C3__", "106", 4}, + {"atxmega256d3", "__AVR_ATxmega256D3__", "106", 4}, + {"atxmega384c3", "__AVR_ATxmega384C3__", "106", 6}, + {"atxmega384d3", "__AVR_ATxmega384D3__", "106", 6}, + {"avrxmega7", NULL, "107", 2}, + {"atxmega128a1", "__AVR_ATxmega128A1__", "107", 2}, + {"atxmega128a1u", "__AVR_ATxmega128A1U__", "107", 2}, + {"atxmega128a4u", "__AVR_ATxmega128A4U__", "107", 2}, + {"avrtiny", NULL, "100", 0}, + {"attiny4", "__AVR_ATtiny4__", "100", 0}, + {"attiny5", "__AVR_ATtiny5__", "100", 0}, + {"attiny9", "__AVR_ATtiny9__", "100", 0}, + {"attiny10", "__AVR_ATtiny10__", "100", 0}, + {"attiny20", "__AVR_ATtiny20__", "100", 0}, + {"attiny40", "__AVR_ATtiny40__", "100", 0}, + {"attiny102", "__AVR_ATtiny102__", "100", 0}, + {"attiny104", "__AVR_ATtiny104__", "100", 0}, + {"avrxmega3", NULL, "103", 1}, + {"attiny202", "__AVR_ATtiny202__", "103", 1}, + {"attiny402", "__AVR_ATtiny402__", "103", 1}, + {"attiny204", "__AVR_ATtiny204__", "103", 1}, + {"attiny404", "__AVR_ATtiny404__", "103", 1}, + {"attiny804", "__AVR_ATtiny804__", "103", 1}, + {"attiny1604", "__AVR_ATtiny1604__", "103", 1}, + {"attiny406", "__AVR_ATtiny406__", "103", 1}, + {"attiny806", "__AVR_ATtiny806__", "103", 1}, + {"attiny1606", "__AVR_ATtiny1606__", "103", 1}, + {"attiny807", "__AVR_ATtiny807__", "103", 1}, + {"attiny1607", "__AVR_ATtiny1607__", "103", 1}, + {"attiny212", "__AVR_ATtiny212__", "103", 1}, + {"attiny412", "__AVR_ATtiny412__", "103", 1}, + {"attiny214", "__AVR_ATtiny214__", "103", 1}, + {"attiny414", "__AVR_ATtiny414__", "103", 1}, + {"attiny814", "__AVR_ATtiny814__", "103", 1}, + {"attiny1614", "__AVR_ATtiny1614__", "103", 1}, + {"attiny416", "__AVR_ATtiny416__", "103", 1}, + {"attiny816", "__AVR_ATtiny816__", "103", 1}, + {"attiny1616", "__AVR_ATtiny1616__", "103", 1}, + {"attiny3216", "__AVR_ATtiny3216__", "103", 1}, + {"attiny417", "__AVR_ATtiny417__", "103", 1}, + {"attiny817", "__AVR_ATtiny817__", "103", 1}, + {"attiny1617", "__AVR_ATtiny1617__", "103", 1}, + {"attiny3217", "__AVR_ATtiny3217__", "103", 1}, + {"attiny1624", "__AVR_ATtiny1624__", "103", 1}, + {"attiny1626", "__AVR_ATtiny1626__", "103", 1}, + {"attiny1627", "__AVR_ATtiny1627__", "103", 1}, + {"atmega808", "__AVR_ATmega808__", "103", 1}, + {"atmega809", "__AVR_ATmega809__", "103", 1}, + {"atmega1608", "__AVR_ATmega1608__", "103", 1}, + {"atmega1609", "__AVR_ATmega1609__", "103", 1}, + {"atmega3208", "__AVR_ATmega3208__", "103", 1}, + {"atmega3209", "__AVR_ATmega3209__", "103", 1}, + {"atmega4808", "__AVR_ATmega4808__", "103", 1}, + {"atmega4809", "__AVR_ATmega4809__", "103", 1}, }; } // namespace targets } // namespace clang -static constexpr llvm::StringLiteral ValidFamilyNames[] = { - "avr1", "avr2", "avr25", "avr3", "avr31", - "avr35", "avr4", "avr5", "avr51", "avr6", - "avrxmega1", "avrxmega2", "avrxmega3", "avrxmega4", "avrxmega5", - "avrxmega6", "avrxmega7", "avrtiny"}; +static bool ArchHasELPM(StringRef Arch) { + return llvm::StringSwitch<bool>(Arch) + .Cases("31", "51", "6", true) + .Cases("102", "104", "105", "106", "107", true) + .Default(false); +} -bool AVRTargetInfo::isValidCPUName(StringRef Name) const { - bool IsFamily = - llvm::find(ValidFamilyNames, Name) != std::end(ValidFamilyNames); +static bool ArchHasELPMX(StringRef Arch) { + return llvm::StringSwitch<bool>(Arch) + .Cases("51", "6", true) + .Cases("102", "104", "105", "106", "107", true) + .Default(false); +} + +static bool ArchHasMOVW(StringRef Arch) { + return llvm::StringSwitch<bool>(Arch) + .Cases("25", "35", "4", "5", "51", "6", true) + .Cases("102", "103", "104", "105", "106", "107", true) + .Default(false); +} + +static bool ArchHasLPMX(StringRef Arch) { + return ArchHasMOVW(Arch); // same architectures +} + +static bool ArchHasMUL(StringRef Arch) { + return llvm::StringSwitch<bool>(Arch) + .Cases("4", "5", "51", "6", true) + .Cases("102", "103", "104", "105", "106", "107", true) + .Default(false); +} + +static bool ArchHasJMPCALL(StringRef Arch) { + return llvm::StringSwitch<bool>(Arch) + .Cases("3", "31", "35", "5", "51", "6", true) + .Cases("102", "103", "104", "105", "106", "107", true) + .Default(false); +} + +static bool ArchHas3BytePC(StringRef Arch) { + // These devices have more than 128kB of program memory. + // Note: + // - Not fully correct for arch 106: only about half the chips have more + // than 128kB program memory and therefore a 3 byte PC. + // - Doesn't match GCC entirely: avr-gcc thinks arch 107 goes beyond 128kB + // but in fact it doesn't. + return llvm::StringSwitch<bool>(Arch) + .Case("6", true) + .Case("106", true) + .Default(false); +} - bool IsMCU = - llvm::find_if(AVRMcus, [&](const MCUInfo &Info) { - return Info.Name == Name; - }) != std::end(AVRMcus); - return IsFamily || IsMCU; +bool AVRTargetInfo::isValidCPUName(StringRef Name) const { + return llvm::any_of( + AVRMcus, [&](const MCUInfo &Info) { return Info.Name == Name; }); } void AVRTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { - Values.append(std::begin(ValidFamilyNames), std::end(ValidFamilyNames)); for (const MCUInfo &Info : AVRMcus) Values.push_back(Info.Name); } +bool AVRTargetInfo::setCPU(const std::string &Name) { + // Set the ABI field based on the device or family name. + auto It = llvm::find_if( + AVRMcus, [&](const MCUInfo &Info) { return Info.Name == Name; }); + if (It != std::end(AVRMcus)) { + CPU = Name; + ABI = (It->Arch == "100") ? "avrtiny" : "avr"; + DefineName = It->DefineName; + Arch = It->Arch; + NumFlashBanks = It->NumFlashBanks; + return true; + } + + // Parameter Name is neither valid family name nor valid device name. + return false; +} + +std::optional<std::string> +AVRTargetInfo::handleAsmEscapedChar(char EscChar) const { + switch (EscChar) { + // "%~" represents for 'r' depends on the device has long jump/call. + case '~': + return ArchHasJMPCALL(Arch) ? std::string("") : std::string(1, 'r'); + + // "%!" represents for 'e' depends on the PC register size. + case '!': + return ArchHas3BytePC(Arch) ? std::string(1, 'e') : std::string(""); + + // This is an invalid escape character for AVR. + default: + return std::nullopt; + } +} + void AVRTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("AVR"); Builder.defineMacro("__AVR"); Builder.defineMacro("__AVR__"); - Builder.defineMacro("__ELF__"); - Builder.defineMacro("__flash", "__attribute__((address_space(1)))"); - if (!this->CPU.empty()) { - auto It = llvm::find_if( - AVRMcus, [&](const MCUInfo &Info) { return Info.Name == this->CPU; }); + if (ABI == "avrtiny") + Builder.defineMacro("__AVR_TINY__", "1"); - if (It != std::end(AVRMcus)) - Builder.defineMacro(It->DefineName); + if (DefineName.size() != 0) + Builder.defineMacro(DefineName); + + Builder.defineMacro("__AVR_ARCH__", Arch); + + // TODO: perhaps we should use the information from AVRDevices.td instead? + if (ArchHasELPM(Arch)) + Builder.defineMacro("__AVR_HAVE_ELPM__"); + if (ArchHasELPMX(Arch)) + Builder.defineMacro("__AVR_HAVE_ELPMX__"); + if (ArchHasMOVW(Arch)) + Builder.defineMacro("__AVR_HAVE_MOVW__"); + if (ArchHasLPMX(Arch)) + Builder.defineMacro("__AVR_HAVE_LPMX__"); + if (ArchHasMUL(Arch)) + Builder.defineMacro("__AVR_HAVE_MUL__"); + if (ArchHasJMPCALL(Arch)) + Builder.defineMacro("__AVR_HAVE_JMP_CALL__"); + if (ArchHas3BytePC(Arch)) { + // Note: some devices do support eijmp/eicall even though this macro isn't + // set. This is the case if they have less than 128kB flash and so + // eijmp/eicall isn't very useful anyway. (This matches gcc, although it's + // debatable whether we should be bug-compatible in this case). + Builder.defineMacro("__AVR_HAVE_EIJMP_EICALL__"); + Builder.defineMacro("__AVR_3_BYTE_PC__"); + } else { + Builder.defineMacro("__AVR_2_BYTE_PC__"); } + + if (NumFlashBanks >= 1) + Builder.defineMacro("__flash", "__attribute__((__address_space__(1)))"); + if (NumFlashBanks >= 2) + Builder.defineMacro("__flash1", "__attribute__((__address_space__(2)))"); + if (NumFlashBanks >= 3) + Builder.defineMacro("__flash2", "__attribute__((__address_space__(3)))"); + if (NumFlashBanks >= 4) + Builder.defineMacro("__flash3", "__attribute__((__address_space__(4)))"); + if (NumFlashBanks >= 5) + Builder.defineMacro("__flash4", "__attribute__((__address_space__(5)))"); + if (NumFlashBanks >= 6) + Builder.defineMacro("__flash5", "__attribute__((__address_space__(6)))"); } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AVR.h b/contrib/llvm-project/clang/lib/Basic/Targets/AVR.h index 89a80ca6a39a..9376c46cd98c 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/AVR.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/AVR.h @@ -15,8 +15,8 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { @@ -61,25 +61,26 @@ public: void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return std::nullopt; + } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; } - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } ArrayRef<const char *> getGCCRegNames() const override { static const char *const GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", - "r20", "r21", "r22", "r23", "r24", "r25", "X", "Y", "Z", "SP" - }; - return llvm::makeArrayRef(GCCRegNames); + "r20", "r21", "r22", "r23", "r24", "r25", "X", "Y", "Z", "SP"}; + return llvm::ArrayRef(GCCRegNames); } ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { - return None; + return std::nullopt; } ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override { @@ -89,7 +90,7 @@ public: {{"r30", "r31"}, 28}, {{"SPL", "SPH"}, 29}, }; - return llvm::makeArrayRef(AddlRegNames); + return llvm::ArrayRef(AddlRegNames); } bool validateAsmConstraint(const char *&Name, @@ -145,7 +146,9 @@ public: case 'R': // Integer constant (Range: -6 to 5) Info.setRequiresImmediate(-6, 5); return true; - case 'G': // Floating point constant + case 'G': // Floating point constant 0.0 + Info.setRequiresImmediate(0); + return true; case 'Q': // A memory address based on Y or Z pointer with displacement. return true; } @@ -168,15 +171,16 @@ public: bool isValidCPUName(StringRef Name) const override; void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; - bool setCPU(const std::string &Name) override { - bool isValid = isValidCPUName(Name); - if (isValid) - CPU = Name; - return isValid; - } + bool setCPU(const std::string &Name) override; + std::optional<std::string> handleAsmEscapedChar(char EscChar) const override; + StringRef getABI() const override { return ABI; } protected: std::string CPU; + StringRef ABI; + StringRef DefineName; + StringRef Arch; + int NumFlashBanks = 0; }; } // namespace targets diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/BPF.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/BPF.cpp index 0b0298df30a5..e713e0847922 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/BPF.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/BPF.cpp @@ -19,9 +19,9 @@ using namespace clang; using namespace clang::targets; -const Builtin::Info BPFTargetInfo::BuiltinInfo[] = { +static constexpr Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsBPF.def" }; @@ -29,13 +29,44 @@ void BPFTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__bpf__"); Builder.defineMacro("__BPF__"); + + std::string CPU = getTargetOpts().CPU; + if (CPU == "probe") { + Builder.defineMacro("__BPF_CPU_VERSION__", "0"); + return; + } + if (CPU.empty() || CPU == "generic" || CPU == "v1") { + Builder.defineMacro("__BPF_CPU_VERSION__", "1"); + return; + } + + std::string CpuVerNumStr = CPU.substr(1); + Builder.defineMacro("__BPF_CPU_VERSION__", CpuVerNumStr); + + int CpuVerNum = std::stoi(CpuVerNumStr); + if (CpuVerNum >= 2) + Builder.defineMacro("__BPF_FEATURE_JMP_EXT"); + + if (CpuVerNum >= 3) { + Builder.defineMacro("__BPF_FEATURE_JMP32"); + Builder.defineMacro("__BPF_FEATURE_ALU32"); + } + + if (CpuVerNum >= 4) { + Builder.defineMacro("__BPF_FEATURE_LDSX"); + Builder.defineMacro("__BPF_FEATURE_MOVSX"); + Builder.defineMacro("__BPF_FEATURE_BSWAP"); + Builder.defineMacro("__BPF_FEATURE_SDIV_SMOD"); + Builder.defineMacro("__BPF_FEATURE_GOTOL"); + Builder.defineMacro("__BPF_FEATURE_ST"); + } } static constexpr llvm::StringLiteral ValidCPUNames[] = {"generic", "v1", "v2", - "v3", "probe"}; + "v3", "v4", "probe"}; bool BPFTargetInfo::isValidCPUName(StringRef Name) const { - return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); + return llvm::is_contained(ValidCPUNames, Name); } void BPFTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { @@ -43,8 +74,8 @@ void BPFTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { } ArrayRef<Builtin::Info> BPFTargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfo, clang::BPF::LastTSBuiltin - - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfo, + clang::BPF::LastTSBuiltin - Builtin::FirstTSBuiltin); } bool BPFTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/BPF.h b/contrib/llvm-project/clang/lib/Basic/Targets/BPF.h index 393a91ff53a5..489f29fc4fea 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/BPF.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/BPF.h @@ -15,14 +15,13 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo { - static const Builtin::Info BuiltinInfo[]; bool HasAlu32 = false; public: @@ -61,14 +60,16 @@ public: ArrayRef<Builtin::Info> getTargetBuiltins() const override; - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; } bool isValidGCCRegisterName(StringRef Name) const override { return true; } - ArrayRef<const char *> getGCCRegNames() const override { return None; } + ArrayRef<const char *> getGCCRegNames() const override { + return std::nullopt; + } bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override { @@ -85,7 +86,7 @@ public: } ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { - return None; + return std::nullopt; } bool allowDebugInfoForExternalRef() const override { return true; } @@ -105,7 +106,7 @@ public: void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; bool setCPU(const std::string &Name) override { - if (Name == "v3") { + if (Name == "v3" || Name == "v4") { HasAlu32 = true; } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.cpp new file mode 100644 index 000000000000..851f27dbb1e5 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.cpp @@ -0,0 +1,315 @@ +//===--- CSKY.cpp - Implement CSKY 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 CSKY TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#include "CSKY.h" + +using namespace clang; +using namespace clang::targets; + +bool CSKYTargetInfo::isValidCPUName(StringRef Name) const { + return llvm::CSKY::parseCPUArch(Name) != llvm::CSKY::ArchKind::INVALID; +} + +bool CSKYTargetInfo::setCPU(const std::string &Name) { + llvm::CSKY::ArchKind archKind = llvm::CSKY::parseCPUArch(Name); + bool isValid = (archKind != llvm::CSKY::ArchKind::INVALID); + + if (isValid) { + CPU = Name; + Arch = archKind; + } + + return isValid; +} + +void CSKYTargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + Builder.defineMacro("__csky__", "2"); + Builder.defineMacro("__CSKY__", "2"); + Builder.defineMacro("__ckcore__", "2"); + Builder.defineMacro("__CKCORE__", "2"); + + Builder.defineMacro("__CSKYABI__", ABI == "abiv2" ? "2" : "1"); + Builder.defineMacro("__cskyabi__", ABI == "abiv2" ? "2" : "1"); + + StringRef ArchName = "ck810"; + StringRef CPUName = "ck810"; + + if (Arch != llvm::CSKY::ArchKind::INVALID) { + ArchName = llvm::CSKY::getArchName(Arch); + CPUName = CPU; + } + + Builder.defineMacro("__" + ArchName.upper() + "__"); + Builder.defineMacro("__" + ArchName.lower() + "__"); + if (ArchName != CPUName) { + Builder.defineMacro("__" + CPUName.upper() + "__"); + Builder.defineMacro("__" + CPUName.lower() + "__"); + } + + // TODO: Add support for BE if BE was supported later + StringRef endian = "__cskyLE__"; + + Builder.defineMacro(endian); + Builder.defineMacro(endian.upper()); + Builder.defineMacro(endian.lower()); + + if (DSPV2) { + StringRef dspv2 = "__CSKY_DSPV2__"; + Builder.defineMacro(dspv2); + Builder.defineMacro(dspv2.lower()); + } + + if (VDSPV2) { + StringRef vdspv2 = "__CSKY_VDSPV2__"; + Builder.defineMacro(vdspv2); + Builder.defineMacro(vdspv2.lower()); + + if (HardFloat) { + StringRef vdspv2_f = "__CSKY_VDSPV2_F__"; + Builder.defineMacro(vdspv2_f); + Builder.defineMacro(vdspv2_f.lower()); + } + } + if (VDSPV1) { + StringRef vdspv1_64 = "__CSKY_VDSP64__"; + StringRef vdspv1_128 = "__CSKY_VDSP128__"; + + Builder.defineMacro(vdspv1_64); + Builder.defineMacro(vdspv1_64.lower()); + Builder.defineMacro(vdspv1_128); + Builder.defineMacro(vdspv1_128.lower()); + } + if (is3E3R1) { + StringRef is3e3r1 = "__CSKY_3E3R1__"; + Builder.defineMacro(is3e3r1); + Builder.defineMacro(is3e3r1.lower()); + } +} + +bool CSKYTargetInfo::hasFeature(StringRef Feature) const { + return llvm::StringSwitch<bool>(Feature) + .Case("hard-float", HardFloat) + .Case("hard-float-abi", HardFloatABI) + .Case("fpuv2_sf", FPUV2_SF) + .Case("fpuv2_df", FPUV2_DF) + .Case("fpuv3_sf", FPUV3_SF) + .Case("fpuv3_df", FPUV3_DF) + .Case("vdspv2", VDSPV2) + .Case("dspv2", DSPV2) + .Case("vdspv1", VDSPV1) + .Case("3e3r1", is3E3R1) + .Default(false); +} + +bool CSKYTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) { + for (const auto &Feature : Features) { + if (Feature == "+hard-float") + HardFloat = true; + if (Feature == "+hard-float-abi") + HardFloatABI = true; + if (Feature == "+fpuv2_sf") + FPUV2_SF = true; + if (Feature == "+fpuv2_df") + FPUV2_DF = true; + if (Feature == "+fpuv3_sf") + FPUV3_SF = true; + if (Feature == "+fpuv3_df") + FPUV3_DF = true; + if (Feature == "+vdspv2") + VDSPV2 = true; + if (Feature == "+dspv2") + DSPV2 = true; + if (Feature == "+vdspv1") + VDSPV1 = true; + if (Feature == "+3e3r1") + is3E3R1 = true; + } + + return true; +} + +ArrayRef<Builtin::Info> CSKYTargetInfo::getTargetBuiltins() const { + return ArrayRef<Builtin::Info>(); +} + +ArrayRef<const char *> CSKYTargetInfo::getGCCRegNames() const { + static const char *const GCCRegNames[] = { + // Integer registers + "r0", + "r1", + "r2", + "r3", + "r4", + "r5", + "r6", + "r7", + "r8", + "r9", + "r10", + "r11", + "r12", + "r13", + "r14", + "r15", + "r16", + "r17", + "r18", + "r19", + "r20", + "r21", + "r22", + "r23", + "r24", + "r25", + "r26", + "r27", + "r28", + "r29", + "r30", + "r31", + + // Floating point registers + "fr0", + "fr1", + "fr2", + "fr3", + "fr4", + "fr5", + "fr6", + "fr7", + "fr8", + "fr9", + "fr10", + "fr11", + "fr12", + "fr13", + "fr14", + "fr15", + "fr16", + "fr17", + "fr18", + "fr19", + "fr20", + "fr21", + "fr22", + "fr23", + "fr24", + "fr25", + "fr26", + "fr27", + "fr28", + "fr29", + "fr30", + "fr31", + + }; + return llvm::ArrayRef(GCCRegNames); +} + +ArrayRef<TargetInfo::GCCRegAlias> CSKYTargetInfo::getGCCRegAliases() const { + static const TargetInfo::GCCRegAlias GCCRegAliases[] = { + {{"a0"}, "r0"}, + {{"a1"}, "r1"}, + {{"a2"}, "r2"}, + {{"a3"}, "r3"}, + {{"l0"}, "r4"}, + {{"l1"}, "r5"}, + {{"l2"}, "r6"}, + {{"l3"}, "r7"}, + {{"l4"}, "r8"}, + {{"l5"}, "r9"}, + {{"l6"}, "r10"}, + {{"l7"}, "r11"}, + {{"t0"}, "r12"}, + {{"t1"}, "r13"}, + {{"sp"}, "r14"}, + {{"lr"}, "r15"}, + {{"l8"}, "r16"}, + {{"l9"}, "r17"}, + {{"t2"}, "r18"}, + {{"t3"}, "r19"}, + {{"t4"}, "r20"}, + {{"t5"}, "r21"}, + {{"t6"}, "r22"}, + {{"t7", "fp"}, "r23"}, + {{"t8", "top"}, "r24"}, + {{"t9", "bsp"}, "r25"}, + {{"r26"}, "r26"}, + {{"r27"}, "r27"}, + {{"gb", "rgb", "rdb"}, "r28"}, + {{"tb", "rtb"}, "r29"}, + {{"svbr"}, "r30"}, + {{"tls"}, "r31"}, + + {{"vr0"}, "fr0"}, + {{"vr1"}, "fr1"}, + {{"vr2"}, "fr2"}, + {{"vr3"}, "fr3"}, + {{"vr4"}, "fr4"}, + {{"vr5"}, "fr5"}, + {{"vr6"}, "fr6"}, + {{"vr7"}, "fr7"}, + {{"vr8"}, "fr8"}, + {{"vr9"}, "fr9"}, + {{"vr10"}, "fr10"}, + {{"vr11"}, "fr11"}, + {{"vr12"}, "fr12"}, + {{"vr13"}, "fr13"}, + {{"vr14"}, "fr14"}, + {{"vr15"}, "fr15"}, + {{"vr16"}, "fr16"}, + {{"vr17"}, "fr17"}, + {{"vr18"}, "fr18"}, + {{"vr19"}, "fr19"}, + {{"vr20"}, "fr20"}, + {{"vr21"}, "fr21"}, + {{"vr22"}, "fr22"}, + {{"vr23"}, "fr23"}, + {{"vr24"}, "fr24"}, + {{"vr25"}, "fr25"}, + {{"vr26"}, "fr26"}, + {{"vr27"}, "fr27"}, + {{"vr28"}, "fr28"}, + {{"vr29"}, "fr29"}, + {{"vr30"}, "fr30"}, + {{"vr31"}, "fr31"}, + + }; + return llvm::ArrayRef(GCCRegAliases); +} + +bool CSKYTargetInfo::validateAsmConstraint( + const char *&Name, TargetInfo::ConstraintInfo &Info) const { + switch (*Name) { + default: + return false; + case 'a': + case 'b': + case 'c': + case 'y': + case 'l': + case 'h': + case 'w': + case 'v': // A floating-point and vector register. + case 'z': + Info.setAllowsRegister(); + return true; + } +} + +unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size) const { + if (Size >= 32) + return 32; + return 0; +} diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.h b/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.h new file mode 100644 index 000000000000..11404e37db36 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.h @@ -0,0 +1,107 @@ +//===--- CSKY.h - Declare CSKY 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 CSKY TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_CSKY_H +#define LLVM_CLANG_LIB_BASIC_TARGETS_CSKY_H + +#include "clang/Basic/MacroBuilder.h" +#include "clang/Basic/TargetInfo.h" +#include "llvm/TargetParser/CSKYTargetParser.h" + +namespace clang { +namespace targets { + +class LLVM_LIBRARY_VISIBILITY CSKYTargetInfo : public TargetInfo { +protected: + std::string ABI; + llvm::CSKY::ArchKind Arch = llvm::CSKY::ArchKind::INVALID; + std::string CPU; + + bool HardFloat = false; + bool HardFloatABI = false; + bool FPUV2_SF = false; + bool FPUV2_DF = false; + bool FPUV3_SF = false; + bool FPUV3_DF = false; + bool VDSPV2 = false; + bool VDSPV1 = false; + bool DSPV2 = false; + bool is3E3R1 = false; + +public: + CSKYTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : TargetInfo(Triple) { + NoAsmVariants = true; + LongLongAlign = 32; + SuitableAlign = 32; + DoubleAlign = LongDoubleAlign = 32; + SizeType = UnsignedInt; + PtrDiffType = SignedInt; + IntPtrType = SignedInt; + WCharType = SignedInt; + WIntType = UnsignedInt; + + UseZeroLengthBitfieldAlignment = true; + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; + resetDataLayout("e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-" + "v64:32:32-v128:32:32-a:0:32-Fi32-n32"); + + setABI("abiv2"); + } + + StringRef getABI() const override { return ABI; } + bool setABI(const std::string &Name) override { + if (Name == "abiv2" || Name == "abiv1") { + ABI = Name; + return true; + } + return false; + } + + bool setCPU(const std::string &Name) override; + + bool isValidCPUName(StringRef Name) const override; + + unsigned getMinGlobalAlign(uint64_t) const override; + + ArrayRef<Builtin::Info> getTargetBuiltins() const override; + + BuiltinVaListKind getBuiltinVaListKind() const override { + return VoidPtrBuiltinVaList; + } + + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &info) const override; + + std::string_view getClobbers() const override { return ""; } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; + bool hasFeature(StringRef Feature) const override; + bool handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) override; + + /// Whether target allows to overalign ABI-specified preferred alignment + bool allowsLargerPreferedTypeAlignment() const override { return false; } + + bool hasBitIntType() const override { return true; } + +protected: + ArrayRef<const char *> getGCCRegNames() const override; + + ArrayRef<GCCRegAlias> getGCCRegAliases() const override; +}; + +} // namespace targets +} // namespace clang + +#endif // LLVM_CLANG_LIB_BASIC_TARGETS_CSKY_H diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/DirectX.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/DirectX.cpp new file mode 100644 index 000000000000..0dd27e6e93b3 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Basic/Targets/DirectX.cpp @@ -0,0 +1,22 @@ +//===--- DirectX.cpp - Implement DirectX 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 DirectX TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#include "DirectX.h" +#include "Targets.h" + +using namespace clang; +using namespace clang::targets; + +void DirectXTargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + DefineStd(Builder, "DIRECTX", Opts); +} diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/DirectX.h b/contrib/llvm-project/clang/lib/Basic/Targets/DirectX.h new file mode 100644 index 000000000000..acfcc8c47ba9 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Basic/Targets/DirectX.h @@ -0,0 +1,103 @@ +//===--- DirectX.h - Declare DirectX 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 DXIL TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_DIRECTX_H +#define LLVM_CLANG_LIB_BASIC_TARGETS_DIRECTX_H +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" +#include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" + +namespace clang { +namespace targets { + +static const unsigned DirectXAddrSpaceMap[] = { + 0, // Default + 1, // opencl_global + 3, // opencl_local + 2, // opencl_constant + 0, // opencl_private + 4, // opencl_generic + 5, // opencl_global_device + 6, // opencl_global_host + 0, // cuda_device + 0, // cuda_constant + 0, // cuda_shared + // SYCL address space values for this map are dummy + 0, // sycl_global + 0, // sycl_global_device + 0, // sycl_global_host + 0, // sycl_local + 0, // sycl_private + 0, // ptr32_sptr + 0, // ptr32_uptr + 0, // ptr64 + 3, // hlsl_groupshared + // Wasm address space values for this target are dummy values, + // as it is only enabled for Wasm targets. + 20, // wasm_funcref +}; + +class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo { +public: + DirectXTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { + TLSSupported = false; + VLASupported = false; + LongWidth = LongAlign = 64; + AddrSpaceMap = &DirectXAddrSpaceMap; + UseAddrSpaceMapMangling = true; + HasLegalHalfType = true; + HasFloat16 = true; + NoAsmVariants = true; + PlatformMinVersion = Triple.getOSVersion(); + PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); + resetDataLayout("e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:" + "32-f64:64-n8:16:32:64"); + TheCXXABI.set(TargetCXXABI::Microsoft); + } + bool useFP16ConversionIntrinsics() const override { return false; } + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; + + bool hasFeature(StringRef Feature) const override { + return Feature == "directx"; + } + + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return std::nullopt; + } + + std::string_view getClobbers() const override { return ""; } + + ArrayRef<const char *> getGCCRegNames() const override { + return std::nullopt; + } + + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &info) const override { + return true; + } + + ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { + return std::nullopt; + } + + BuiltinVaListKind getBuiltinVaListKind() const override { + return TargetInfo::VoidPtrBuiltinVaList; + } +}; + +} // namespace targets +} // namespace clang + +#endif // LLVM_CLANG_LIB_BASIC_TARGETS_DIRECTX_H diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp index 9c37dee7e89a..ac747e371fb4 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp @@ -24,8 +24,6 @@ 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; @@ -68,6 +66,18 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, } else if (CPU == "hexagonv68") { Builder.defineMacro("__HEXAGON_V68__"); Builder.defineMacro("__HEXAGON_ARCH__", "68"); + } else if (CPU == "hexagonv69") { + Builder.defineMacro("__HEXAGON_V69__"); + Builder.defineMacro("__HEXAGON_ARCH__", "69"); + } else if (CPU == "hexagonv71") { + Builder.defineMacro("__HEXAGON_V71__"); + Builder.defineMacro("__HEXAGON_ARCH__", "71"); + } else if (CPU == "hexagonv71t") { + Builder.defineMacro("__HEXAGON_V71T__"); + Builder.defineMacro("__HEXAGON_ARCH__", "71"); + } else if (CPU == "hexagonv73") { + Builder.defineMacro("__HEXAGON_V73__"); + Builder.defineMacro("__HEXAGON_ARCH__", "73"); } if (hasFeature("hvx-length64b")) { @@ -90,6 +100,11 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, std::string NumPhySlots = isTinyCore() ? "3" : "4"; Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots); + + 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"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); } bool HexagonTargetInfo::initFeatureMap( @@ -128,6 +143,10 @@ bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, else if (F == "+audio") HasAudio = true; } + if (CPU.compare("hexagonv68") >= 0) { + HasLegalHalfType = true; + HasFloat16 = true; + } return true; } @@ -166,7 +185,7 @@ const char *const HexagonTargetInfo::GCCRegNames[] = { }; ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = { @@ -176,16 +195,16 @@ const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = { }; ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const { - return llvm::makeArrayRef(GCCRegAliases); + return llvm::ArrayRef(GCCRegAliases); } -const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { +static constexpr Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HEADER, ALL_LANGUAGES}, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsHexagon.def" }; @@ -214,7 +233,9 @@ static constexpr CPUSuffix Suffixes[] = { {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}}, {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}}, {{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}}, - {{"hexagonv68"}, {"68"}}, + {{"hexagonv68"}, {"68"}}, {{"hexagonv69"}, {"69"}}, + {{"hexagonv71"}, {"71"}}, {{"hexagonv71t"}, {"71t"}}, + {{"hexagonv73"}, {"73"}}, }; const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) { @@ -232,6 +253,6 @@ void HexagonTargetInfo::fillValidCPUList( } ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin - - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin - + Builtin::FirstTSBuiltin); } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.h b/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.h index d6c7da5f1e40..cdb47dbae799 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.h @@ -15,8 +15,8 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { @@ -24,7 +24,6 @@ namespace targets { // Hexagon abstract base class class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo { - static const Builtin::Info BuiltinInfo[]; static const char *const GCCRegNames[]; static const TargetInfo::GCCRegAlias GCCRegAliases[]; std::string CPU; @@ -113,7 +112,7 @@ public: ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } static const char *getHexagonCPUSuffix(StringRef Name); @@ -139,7 +138,7 @@ public: return CPU.find('t') != std::string::npos; } - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } }; } // namespace targets } // namespace clang diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.cpp index bb1872083c09..8722a369ed87 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.cpp @@ -24,7 +24,7 @@ const char *const LanaiTargetInfo::GCCRegNames[] = { }; ArrayRef<const char *> LanaiTargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } const TargetInfo::GCCRegAlias LanaiTargetInfo::GCCRegAliases[] = { @@ -33,7 +33,7 @@ const TargetInfo::GCCRegAlias LanaiTargetInfo::GCCRegAliases[] = { }; ArrayRef<TargetInfo::GCCRegAlias> LanaiTargetInfo::getGCCRegAliases() const { - return llvm::makeArrayRef(GCCRegAliases); + return llvm::ArrayRef(GCCRegAliases); } bool LanaiTargetInfo::isValidCPUName(StringRef Name) const { diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.h b/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.h index 9af5427b81c4..144cbc7de989 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.h @@ -15,8 +15,8 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { @@ -78,16 +78,18 @@ public: return TargetInfo::VoidPtrBuiltinVaList; } - ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return std::nullopt; + } bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override { return false; } - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } }; } // namespace targets } // namespace clang diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Le64.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/Le64.cpp index 5c961ff81e05..f7afa0e747d6 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/Le64.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/Le64.cpp @@ -27,5 +27,4 @@ void Le64TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { DefineStd(Builder, "unix", Opts); defineCPUMacros(Builder, "le64", /*Tuning=*/false); - Builder.defineMacro("__ELF__"); } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Le64.h b/contrib/llvm-project/clang/lib/Basic/Targets/Le64.h index 13a0b04d9f09..45f6a4e9dd75 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/Le64.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/Le64.h @@ -15,8 +15,8 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { @@ -41,12 +41,14 @@ public: return TargetInfo::PNaClABIBuiltinVaList; } - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } - ArrayRef<const char *> getGCCRegNames() const override { return None; } + ArrayRef<const char *> getGCCRegNames() const override { + return std::nullopt; + } ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { - return None; + return std::nullopt; } bool validateAsmConstraint(const char *&Name, diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp new file mode 100644 index 000000000000..88537989a051 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp @@ -0,0 +1,299 @@ +//===--- LoongArch.cpp - Implement LoongArch 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 LoongArch TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#include "LoongArch.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/MacroBuilder.h" +#include "clang/Basic/TargetBuiltins.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/LoongArchTargetParser.h" + +using namespace clang; +using namespace clang::targets; + +ArrayRef<const char *> LoongArchTargetInfo::getGCCRegNames() const { + static const char *const GCCRegNames[] = { + // General purpose registers. + "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", "$r7", "$r8", "$r9", + "$r10", "$r11", "$r12", "$r13", "$r14", "$r15", "$r16", "$r17", "$r18", + "$r19", "$r20", "$r21", "$r22", "$r23", "$r24", "$r25", "$r26", "$r27", + "$r28", "$r29", "$r30", "$r31", + // Floating point registers. + "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", + "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", + "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", + "$f28", "$f29", "$f30", "$f31", + // Condition flag registers. + "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7", + // 128-bit vector registers. + "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6", "$vr7", "$vr8", + "$vr9", "$vr10", "$vr11", "$vr12", "$vr13", "$vr14", "$vr15", "$vr16", + "$vr17", "$vr18", "$vr19", "$vr20", "$vr21", "$vr22", "$vr23", "$vr24", + "$vr25", "$vr26", "$vr27", "$vr28", "$vr29", "$vr30", "$vr31", + // 256-bit vector registers. + "$xr0", "$xr1", "$xr2", "$xr3", "$xr4", "$xr5", "$xr6", "$xr7", "$xr8", + "$xr9", "$xr10", "$xr11", "$xr12", "$xr13", "$xr14", "$xr15", "$xr16", + "$xr17", "$xr18", "$xr19", "$xr20", "$xr21", "$xr22", "$xr23", "$xr24", + "$xr25", "$xr26", "$xr27", "$xr28", "$xr29", "$xr30", "$xr31"}; + return llvm::ArrayRef(GCCRegNames); +} + +ArrayRef<TargetInfo::GCCRegAlias> +LoongArchTargetInfo::getGCCRegAliases() const { + static const TargetInfo::GCCRegAlias GCCRegAliases[] = { + {{"zero", "$zero", "r0"}, "$r0"}, + {{"ra", "$ra", "r1"}, "$r1"}, + {{"tp", "$tp", "r2"}, "$r2"}, + {{"sp", "$sp", "r3"}, "$r3"}, + {{"a0", "$a0", "r4"}, "$r4"}, + {{"a1", "$a1", "r5"}, "$r5"}, + {{"a2", "$a2", "r6"}, "$r6"}, + {{"a3", "$a3", "r7"}, "$r7"}, + {{"a4", "$a4", "r8"}, "$r8"}, + {{"a5", "$a5", "r9"}, "$r9"}, + {{"a6", "$a6", "r10"}, "$r10"}, + {{"a7", "$a7", "r11"}, "$r11"}, + {{"t0", "$t0", "r12"}, "$r12"}, + {{"t1", "$t1", "r13"}, "$r13"}, + {{"t2", "$t2", "r14"}, "$r14"}, + {{"t3", "$t3", "r15"}, "$r15"}, + {{"t4", "$t4", "r16"}, "$r16"}, + {{"t5", "$t5", "r17"}, "$r17"}, + {{"t6", "$t6", "r18"}, "$r18"}, + {{"t7", "$t7", "r19"}, "$r19"}, + {{"t8", "$t8", "r20"}, "$r20"}, + {{"r21"}, "$r21"}, + {{"s9", "$s9", "r22", "fp", "$fp"}, "$r22"}, + {{"s0", "$s0", "r23"}, "$r23"}, + {{"s1", "$s1", "r24"}, "$r24"}, + {{"s2", "$s2", "r25"}, "$r25"}, + {{"s3", "$s3", "r26"}, "$r26"}, + {{"s4", "$s4", "r27"}, "$r27"}, + {{"s5", "$s5", "r28"}, "$r28"}, + {{"s6", "$s6", "r29"}, "$r29"}, + {{"s7", "$s7", "r30"}, "$r30"}, + {{"s8", "$s8", "r31"}, "$r31"}, + {{"$fa0"}, "$f0"}, + {{"$fa1"}, "$f1"}, + {{"$fa2"}, "$f2"}, + {{"$fa3"}, "$f3"}, + {{"$fa4"}, "$f4"}, + {{"$fa5"}, "$f5"}, + {{"$fa6"}, "$f6"}, + {{"$fa7"}, "$f7"}, + {{"$ft0"}, "$f8"}, + {{"$ft1"}, "$f9"}, + {{"$ft2"}, "$f10"}, + {{"$ft3"}, "$f11"}, + {{"$ft4"}, "$f12"}, + {{"$ft5"}, "$f13"}, + {{"$ft6"}, "$f14"}, + {{"$ft7"}, "$f15"}, + {{"$ft8"}, "$f16"}, + {{"$ft9"}, "$f17"}, + {{"$ft10"}, "$f18"}, + {{"$ft11"}, "$f19"}, + {{"$ft12"}, "$f20"}, + {{"$ft13"}, "$f21"}, + {{"$ft14"}, "$f22"}, + {{"$ft15"}, "$f23"}, + {{"$fs0"}, "$f24"}, + {{"$fs1"}, "$f25"}, + {{"$fs2"}, "$f26"}, + {{"$fs3"}, "$f27"}, + {{"$fs4"}, "$f28"}, + {{"$fs5"}, "$f29"}, + {{"$fs6"}, "$f30"}, + {{"$fs7"}, "$f31"}, + }; + return llvm::ArrayRef(GCCRegAliases); +} + +bool LoongArchTargetInfo::validateAsmConstraint( + const char *&Name, TargetInfo::ConstraintInfo &Info) const { + // See the GCC definitions here: + // https://gcc.gnu.org/onlinedocs/gccint/Machine-Constraints.html + // Note that the 'm' constraint is handled in TargetInfo. + switch (*Name) { + default: + return false; + case 'f': + // A floating-point register (if available). + Info.setAllowsRegister(); + return true; + case 'k': + // A memory operand whose address is formed by a base register and + // (optionally scaled) index register. + Info.setAllowsMemory(); + return true; + case 'l': + // A signed 16-bit constant. + Info.setRequiresImmediate(-32768, 32767); + return true; + case 'I': + // A signed 12-bit constant (for arithmetic instructions). + Info.setRequiresImmediate(-2048, 2047); + return true; + case 'J': + // Integer zero. + Info.setRequiresImmediate(0); + return true; + case 'K': + // An unsigned 12-bit constant (for logic instructions). + Info.setRequiresImmediate(0, 4095); + return true; + case 'Z': + // ZB: An address that is held in a general-purpose register. The offset is + // zero. + // ZC: A memory operand whose address is formed by a base register + // and offset that is suitable for use in instructions with the same + // addressing mode as ll.w and sc.w. + if (Name[1] == 'C' || Name[1] == 'B') { + Info.setAllowsMemory(); + ++Name; // Skip over 'Z'. + return true; + } + return false; + } +} + +std::string +LoongArchTargetInfo::convertConstraint(const char *&Constraint) const { + std::string R; + switch (*Constraint) { + case 'Z': + // "ZC"/"ZB" are two-character constraints; add "^" hint for later + // parsing. + R = "^" + std::string(Constraint, 2); + ++Constraint; + break; + default: + R = TargetInfo::convertConstraint(Constraint); + break; + } + return R; +} + +void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + Builder.defineMacro("__loongarch__"); + unsigned GRLen = getRegisterWidth(); + Builder.defineMacro("__loongarch_grlen", Twine(GRLen)); + if (GRLen == 64) + Builder.defineMacro("__loongarch64"); + + if (HasFeatureD) + Builder.defineMacro("__loongarch_frlen", "64"); + else if (HasFeatureF) + Builder.defineMacro("__loongarch_frlen", "32"); + else + Builder.defineMacro("__loongarch_frlen", "0"); + + // Define __loongarch_arch. + StringRef ArchName = getCPU(); + Builder.defineMacro("__loongarch_arch", Twine('"') + ArchName + Twine('"')); + + // Define __loongarch_tune. + StringRef TuneCPU = getTargetOpts().TuneCPU; + if (TuneCPU.empty()) + TuneCPU = ArchName; + Builder.defineMacro("__loongarch_tune", Twine('"') + TuneCPU + Twine('"')); + + if (HasFeatureLSX) + Builder.defineMacro("__loongarch_sx", Twine(1)); + if (HasFeatureLASX) + Builder.defineMacro("__loongarch_asx", Twine(1)); + + StringRef ABI = getABI(); + if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s") + Builder.defineMacro("__loongarch_lp64"); + + if (ABI == "lp64d" || ABI == "ilp32d") { + Builder.defineMacro("__loongarch_hard_float"); + Builder.defineMacro("__loongarch_double_float"); + } else if (ABI == "lp64f" || ABI == "ilp32f") { + Builder.defineMacro("__loongarch_hard_float"); + Builder.defineMacro("__loongarch_single_float"); + } else if (ABI == "lp64s" || ABI == "ilp32s") { + Builder.defineMacro("__loongarch_soft_float"); + } + + 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"); + if (GRLen == 64) + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); +} + +static constexpr Builtin::Info BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) \ + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#include "clang/Basic/BuiltinsLoongArch.def" +}; + +bool LoongArchTargetInfo::initFeatureMap( + llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, + const std::vector<std::string> &FeaturesVec) const { + if (getTriple().getArch() == llvm::Triple::loongarch64) + Features["64bit"] = true; + if (getTriple().getArch() == llvm::Triple::loongarch32) + Features["32bit"] = true; + + return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); +} + +/// Return true if has this feature. +bool LoongArchTargetInfo::hasFeature(StringRef Feature) const { + bool Is64Bit = getTriple().getArch() == llvm::Triple::loongarch64; + // TODO: Handle more features. + return llvm::StringSwitch<bool>(Feature) + .Case("loongarch32", !Is64Bit) + .Case("loongarch64", Is64Bit) + .Case("32bit", !Is64Bit) + .Case("64bit", Is64Bit) + .Case("lsx", HasFeatureLSX) + .Case("lasx", HasFeatureLASX) + .Default(false); +} + +ArrayRef<Builtin::Info> LoongArchTargetInfo::getTargetBuiltins() const { + return llvm::ArrayRef(BuiltinInfo, clang::LoongArch::LastTSBuiltin - + Builtin::FirstTSBuiltin); +} + +bool LoongArchTargetInfo::handleTargetFeatures( + std::vector<std::string> &Features, DiagnosticsEngine &Diags) { + for (const auto &Feature : Features) { + if (Feature == "+d" || Feature == "+f") { + // "d" implies "f". + HasFeatureF = true; + if (Feature == "+d") { + HasFeatureD = true; + } + } else if (Feature == "+lsx") + HasFeatureLSX = true; + else if (Feature == "+lasx") + HasFeatureLASX = true; + } + return true; +} + +bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const { + return llvm::LoongArch::isValidCPUName(Name); +} + +void LoongArchTargetInfo::fillValidCPUList( + SmallVectorImpl<StringRef> &Values) const { + llvm::LoongArch::fillValidCPUList(Values); +} diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.h b/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.h new file mode 100644 index 000000000000..3313102492cb --- /dev/null +++ b/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.h @@ -0,0 +1,154 @@ +//===-- LoongArch.h - Declare LoongArch 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 LoongArch TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_LOONGARCH_H +#define LLVM_CLANG_LIB_BASIC_TARGETS_LOONGARCH_H + +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" +#include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" + +namespace clang { +namespace targets { + +class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { +protected: + std::string ABI; + std::string CPU; + bool HasFeatureD; + bool HasFeatureF; + bool HasFeatureLSX; + bool HasFeatureLASX; + +public: + LoongArchTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { + HasFeatureD = false; + HasFeatureF = false; + HasFeatureLSX = false; + HasFeatureLASX = false; + LongDoubleWidth = 128; + LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); + MCountName = "_mcount"; + SuitableAlign = 128; + WCharType = SignedInt; + WIntType = UnsignedInt; + } + + bool setCPU(const std::string &Name) override { + if (!isValidCPUName(Name)) + return false; + CPU = Name; + return true; + } + + StringRef getCPU() const { return CPU; } + + StringRef getABI() const override { return ABI; } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; + + ArrayRef<Builtin::Info> getTargetBuiltins() const override; + + BuiltinVaListKind getBuiltinVaListKind() const override { + return TargetInfo::VoidPtrBuiltinVaList; + } + + std::string_view getClobbers() const override { return ""; } + + ArrayRef<const char *> getGCCRegNames() const override; + + int getEHDataRegisterNumber(unsigned RegNo) const override { + if (RegNo == 0) + return 4; + if (RegNo == 1) + return 5; + return -1; + } + + ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; + + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const override; + std::string convertConstraint(const char *&Constraint) const override; + + bool hasBitIntType() const override { return true; } + + bool handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) override; + + bool + initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, + StringRef CPU, + const std::vector<std::string> &FeaturesVec) const override; + + bool hasFeature(StringRef Feature) const override; + + bool isValidCPUName(StringRef Name) const override; + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; +}; + +class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo + : public LoongArchTargetInfo { +public: + LoongArch32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : LoongArchTargetInfo(Triple, Opts) { + IntPtrType = SignedInt; + PtrDiffType = SignedInt; + SizeType = UnsignedInt; + resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128"); + // TODO: select appropriate ABI. + setABI("ilp32d"); + } + + bool setABI(const std::string &Name) override { + if (Name == "ilp32d" || Name == "ilp32f" || Name == "ilp32s") { + ABI = Name; + return true; + } + return false; + } + void setMaxAtomicWidth() override { + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; + } +}; + +class LLVM_LIBRARY_VISIBILITY LoongArch64TargetInfo + : public LoongArchTargetInfo { +public: + LoongArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : LoongArchTargetInfo(Triple, Opts) { + LongWidth = LongAlign = PointerWidth = PointerAlign = 64; + IntMaxType = Int64Type = SignedLong; + resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n64-S128"); + // TODO: select appropriate ABI. + setABI("lp64d"); + } + + bool setABI(const std::string &Name) override { + if (Name == "lp64d" || Name == "lp64f" || Name == "lp64s") { + ABI = Name; + return true; + } + return false; + } + void setMaxAtomicWidth() override { + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + } +}; +} // end namespace targets +} // end namespace clang + +#endif // LLVM_CLANG_LIB_BASIC_TARGETS_LOONGARCH_H diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp index c0cd8fa90ed6..1b7e0a7f32c9 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp @@ -17,19 +17,20 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/TargetParser.h" +#include "llvm/TargetParser/TargetParser.h" #include <cstdint> #include <cstring> #include <limits> +#include <optional> namespace clang { namespace targets { M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple, - const TargetOptions &) - : TargetInfo(Triple) { + const TargetOptions &Opts) + : TargetInfo(Triple), TargetOpts(Opts) { - std::string Layout = ""; + std::string Layout; // M68k is Big Endian Layout += "E"; @@ -79,45 +80,44 @@ void M68kTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__m68k__"); - Builder.defineMacro("mc68000"); - Builder.defineMacro("__mc68000"); - Builder.defineMacro("__mc68000__"); + DefineStd(Builder, "mc68000", Opts); // For sub-architecture switch (CPU) { case CK_68010: - Builder.defineMacro("mc68010"); - Builder.defineMacro("__mc68010"); - Builder.defineMacro("__mc68010__"); + DefineStd(Builder, "mc68010", Opts); break; case CK_68020: - Builder.defineMacro("mc68020"); - Builder.defineMacro("__mc68020"); - Builder.defineMacro("__mc68020__"); + DefineStd(Builder, "mc68020", Opts); break; case CK_68030: - Builder.defineMacro("mc68030"); - Builder.defineMacro("__mc68030"); - Builder.defineMacro("__mc68030__"); + DefineStd(Builder, "mc68030", Opts); break; case CK_68040: - Builder.defineMacro("mc68040"); - Builder.defineMacro("__mc68040"); - Builder.defineMacro("__mc68040__"); + DefineStd(Builder, "mc68040", Opts); break; case CK_68060: - Builder.defineMacro("mc68060"); - Builder.defineMacro("__mc68060"); - Builder.defineMacro("__mc68060__"); + DefineStd(Builder, "mc68060", Opts); break; default: break; } + + if (CPU >= CK_68020) { + 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"); + } + + // Floating point + if (TargetOpts.FeatureMap.lookup("isa-68881") || + TargetOpts.FeatureMap.lookup("isa-68882")) + Builder.defineMacro("__HAVE_68881__"); } ArrayRef<Builtin::Info> M68kTargetInfo::getTargetBuiltins() const { // FIXME: Implement. - return None; + return std::nullopt; } bool M68kTargetInfo::hasFeature(StringRef Feature) const { @@ -131,12 +131,12 @@ const char *const M68kTargetInfo::GCCRegNames[] = { "pc"}; ArrayRef<const char *> M68kTargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } ArrayRef<TargetInfo::GCCRegAlias> M68kTargetInfo::getGCCRegAliases() const { // No aliases. - return None; + return std::nullopt; } bool M68kTargetInfo::validateAsmConstraint( @@ -185,13 +185,19 @@ bool M68kTargetInfo::validateAsmConstraint( break; } break; + case 'Q': // address register indirect addressing + case 'U': // address register indirect w/ constant offset addressing + // TODO: Handle 'S' (basically 'm' when pc-rel is enforced) when + // '-mpcrel' flag is properly handled by the driver. + info.setAllowsMemory(); + return true; default: break; } return false; } -llvm::Optional<std::string> +std::optional<std::string> M68kTargetInfo::handleAsmEscapedChar(char EscChar) const { char C; switch (EscChar) { @@ -209,7 +215,7 @@ M68kTargetInfo::handleAsmEscapedChar(char EscChar) const { C = 'd'; break; default: - return llvm::None; + return std::nullopt; } return std::string(1, C); @@ -223,7 +229,7 @@ std::string M68kTargetInfo::convertConstraint(const char *&Constraint) const { return std::string(1, *Constraint); } -const char *M68kTargetInfo::getClobbers() const { +std::string_view M68kTargetInfo::getClobbers() const { // FIXME: Is this really right? return ""; } @@ -232,5 +238,15 @@ TargetInfo::BuiltinVaListKind M68kTargetInfo::getBuiltinVaListKind() const { return TargetInfo::VoidPtrBuiltinVaList; } +TargetInfo::CallingConvCheckResult +M68kTargetInfo::checkCallingConvention(CallingConv CC) const { + switch (CC) { + case CC_C: + case CC_M68kRTD: + return CCCR_OK; + default: + return TargetInfo::checkCallingConvention(CC); + } +} } // namespace targets } // namespace clang diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/M68k.h b/contrib/llvm-project/clang/lib/Basic/Targets/M68k.h index a42ca674ef9c..a9c262e62fba 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/M68k.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/M68k.h @@ -16,8 +16,9 @@ #include "OSTargets.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" +#include <optional> namespace clang { namespace targets { @@ -35,6 +36,8 @@ class LLVM_LIBRARY_VISIBILITY M68kTargetInfo : public TargetInfo { CK_68060 } CPU = CK_Unknown; + const TargetOptions &TargetOpts; + public: M68kTargetInfo(const llvm::Triple &Triple, const TargetOptions &); @@ -47,10 +50,11 @@ public: std::string convertConstraint(const char *&Constraint) const override; bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override; - llvm::Optional<std::string> handleAsmEscapedChar(char EscChar) const override; - const char *getClobbers() const override; + std::optional<std::string> handleAsmEscapedChar(char EscChar) const override; + std::string_view getClobbers() const override; BuiltinVaListKind getBuiltinVaListKind() const override; bool setCPU(const std::string &Name) override; + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override; }; } // namespace targets diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.cpp index 90890500ae27..844f5d3af703 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.cpp @@ -22,13 +22,12 @@ const char *const MSP430TargetInfo::GCCRegNames[] = { }; ArrayRef<const char *> MSP430TargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } void MSP430TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("MSP430"); Builder.defineMacro("__MSP430__"); - Builder.defineMacro("__ELF__"); // FIXME: defines for different 'flavours' of MCU } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.h b/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.h index 9d42e4d4bb18..25639b8c1e0a 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.h @@ -15,8 +15,8 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { @@ -52,7 +52,7 @@ public: ArrayRef<Builtin::Info> getTargetBuiltins() const override { // FIXME: Implement. - return None; + return std::nullopt; } bool allowsLargerPreferedTypeAlignment() const override { return false; } @@ -71,7 +71,7 @@ public: {{"r2"}, "sr"}, {{"r3"}, "cg"}, }; - return llvm::makeArrayRef(GCCRegAliases); + return llvm::ArrayRef(GCCRegAliases); } bool validateAsmConstraint(const char *&Name, @@ -87,7 +87,7 @@ public: return false; } - const char *getClobbers() const override { + std::string_view getClobbers() const override { // FIXME: Is this really right? return ""; } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Mips.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/Mips.cpp index 3a32fd492c6b..3a65f53c5248 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/Mips.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/Mips.cpp @@ -20,11 +20,11 @@ using namespace clang; using namespace clang::targets; -const Builtin::Info MipsTargetInfo::BuiltinInfo[] = { +static constexpr Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsMips.def" }; @@ -50,7 +50,7 @@ static constexpr llvm::StringLiteral ValidCPUNames[] = { {"octeon"}, {"octeon+"}, {"p5600"}}; bool MipsTargetInfo::isValidCPUName(StringRef Name) const { - return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); + return llvm::is_contained(ValidCPUNames, Name); } void MipsTargetInfo::fillValidCPUList( @@ -149,6 +149,10 @@ void MipsTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("_MIPS_FPSET", Twine(32)); else Builder.defineMacro("_MIPS_FPSET", Twine(16)); + if (NoOddSpreg) + Builder.defineMacro("_MIPS_SPFPSET", Twine(16)); + else + Builder.defineMacro("_MIPS_SPFPSET", Twine(32)); if (IsMips16) Builder.defineMacro("__mips16", Twine(1)); @@ -182,7 +186,7 @@ void MipsTargetInfo::getTargetDefines(const LangOptions &Opts, if (DisableMadd4) Builder.defineMacro("__mips_no_madd4", Twine(1)); - Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0))); + Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(LangAS::Default))); Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth())); Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth())); @@ -192,14 +196,14 @@ void MipsTargetInfo::getTargetDefines(const LangOptions &Opts, else Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper()); - if (StringRef(CPU).startswith("octeon")) + if (StringRef(CPU).starts_with("octeon")) Builder.defineMacro("__OCTEON__"); - // These shouldn't be defined for MIPS-I but there's no need to check - // for that since MIPS-I isn't supported. - 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"); + if (CPU != "mips1") { + 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"); + } // 32-bit MIPS processors don't have the necessary lld/scd instructions // found in 64-bit processors. In the case of O32 on a 64-bit processor, @@ -220,8 +224,8 @@ bool MipsTargetInfo::hasFeature(StringRef Feature) const { } ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfo, clang::Mips::LastTSBuiltin - - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfo, + clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin); } unsigned MipsTargetInfo::getUnwindWordWidth() const { @@ -229,7 +233,7 @@ unsigned MipsTargetInfo::getUnwindWordWidth() const { .Case("o32", 32) .Case("n32", 64) .Case("n64", 64) - .Default(getPointerWidth(0)); + .Default(getPointerWidth(LangAS::Default)); } bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const { @@ -238,12 +242,6 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const { Diags.Report(diag::err_target_unsupported_cpu_for_micromips) << CPU; return false; } - // FIXME: It's valid to use O32 on a 64-bit CPU but the backend can't handle - // this yet. It's better to fail here than on the backend assertion. - if (processorSupportsGPR64() && ABI == "o32") { - Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU; - return false; - } // 64-bit ABI's require 64-bit CPU's. if (!processorSupportsGPR64() && (ABI == "n32" || ABI == "n64")) { @@ -251,24 +249,6 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const { return false; } - // FIXME: It's valid to use O32 on a mips64/mips64el triple but the backend - // can't handle this yet. It's better to fail here than on the - // backend assertion. - if (getTriple().isMIPS64() && ABI == "o32") { - Diags.Report(diag::err_target_unsupported_abi_for_triple) - << ABI << getTriple().str(); - return false; - } - - // FIXME: It's valid to use N32/N64 on a mips/mipsel triple but the backend - // can't handle this yet. It's better to fail here than on the - // backend assertion. - if (getTriple().isMIPS32() && (ABI == "n32" || ABI == "n64")) { - Diags.Report(diag::err_target_unsupported_abi_for_triple) - << ABI << getTriple().str(); - return false; - } - // -fpxx is valid only for the o32 ABI if (FPMode == FPXX && (ABI == "n32" || ABI == "n64")) { Diags.Report(diag::err_unsupported_abi_for_opt) << "-mfpxx" << "o32"; diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Mips.h b/contrib/llvm-project/clang/lib/Basic/Targets/Mips.h index b475c03889a1..23d4e1b598fa 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/Mips.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/Mips.h @@ -15,8 +15,8 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { @@ -40,7 +40,6 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { resetDataLayout(("e-" + Layout).str()); } - static const Builtin::Info BuiltinInfo[]; std::string CPU; bool IsMips16; bool IsMicromips; @@ -54,6 +53,7 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { bool HasMSA; bool DisableMadd4; bool UseIndirectJumpHazard; + bool NoOddSpreg; protected: enum FPModeEnum { FPXX, FP32, FP64 } FPMode; @@ -226,7 +226,7 @@ public: "$msair", "$msacsr", "$msaaccess", "$msasave", "$msamodify", "$msarequest", "$msamap", "$msaunmap" }; - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } bool validateAsmConstraint(const char *&Name, @@ -237,12 +237,14 @@ public: case 'r': // CPU registers. case 'd': // Equivalent to "r" unless generating MIPS16 code. case 'y': // Equivalent to "r", backward compatibility only. - case 'f': // floating-point registers. case 'c': // $25 for indirect jumps case 'l': // lo register case 'x': // hilo register pair Info.setAllowsRegister(); return true; + case 'f': // floating-point registers. + Info.setAllowsRegister(); + return FloatABI != SoftFloat; case 'I': // Signed 16-bit constant case 'J': // Integer 0 case 'K': // Unsigned 16-bit constant @@ -279,7 +281,7 @@ public: return TargetInfo::convertConstraint(Constraint); } - const char *getClobbers() const override { + std::string_view getClobbers() const override { // In GCC, $1 is not widely used in generated code (it's used only in a few // specific situations), so there is no real need for users to add it to // the clobbers list if they want to use it in their inline assembly code. @@ -314,6 +316,8 @@ public: FloatABI = HardFloat; DspRev = NoDSP; FPMode = isFP64Default() ? FP64 : FPXX; + NoOddSpreg = false; + bool OddSpregGiven = false; for (const auto &Feature : Features) { if (Feature == "+single-float") @@ -350,8 +354,18 @@ public: IsNoABICalls = true; else if (Feature == "+use-indirect-jump-hazard") UseIndirectJumpHazard = true; + else if (Feature == "+nooddspreg") { + NoOddSpreg = true; + OddSpregGiven = false; + } else if (Feature == "-nooddspreg") { + NoOddSpreg = false; + OddSpregGiven = true; + } } + if (FPMode == FPXX && !OddSpregGiven) + NoOddSpreg = true; + setDataLayout(); return true; @@ -395,8 +409,8 @@ public: {{"ra"}, "$31"} }; if (ABI == "o32") - return llvm::makeArrayRef(O32RegAliases); - return llvm::makeArrayRef(NewABIRegAliases); + return llvm::ArrayRef(O32RegAliases); + return llvm::ArrayRef(NewABIRegAliases); } bool hasInt128Type() const override { @@ -406,7 +420,7 @@ public: unsigned getUnwindWordWidth() const override; bool validateTarget(DiagnosticsEngine &Diags) const override; - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } }; } // namespace targets } // namespace clang diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp index 56f8a179db3c..c0b5db795e27 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp @@ -16,18 +16,17 @@ #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; -const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = { +static constexpr Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsNVPTX.def" }; @@ -42,31 +41,20 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, PTXVersion = 32; for (const StringRef Feature : Opts.FeaturesAsWritten) { - if (!Feature.startswith("+ptx")) + int PTXV; + if (!Feature.starts_with("+ptx") || + Feature.drop_front(4).getAsInteger(10, PTXV)) continue; - PTXVersion = llvm::StringSwitch<unsigned>(Feature) - .Case("+ptx72", 72) - .Case("+ptx71", 71) - .Case("+ptx70", 70) - .Case("+ptx65", 65) - .Case("+ptx64", 64) - .Case("+ptx63", 63) - .Case("+ptx61", 61) - .Case("+ptx60", 60) - .Case("+ptx50", 50) - .Case("+ptx43", 43) - .Case("+ptx42", 42) - .Case("+ptx41", 41) - .Case("+ptx40", 40) - .Case("+ptx32", 32) - .Default(32); + PTXVersion = PTXV; // TODO: should it be max(PTXVersion, PTXV)? } TLSSupported = false; VLASupported = false; AddrSpaceMap = &NVPTXAddrSpaceMap; - GridValues = llvm::omp::NVPTXGpuGridValues; UseAddrSpaceMapMangling = true; + // __bf16 is always available as a load/store only type. + BFloat16Width = BFloat16Align = 16; + BFloat16Format = &llvm::APFloat::BFloat(); // Define available target features // These must be defined in sorted order! @@ -85,7 +73,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, // types. llvm::Triple HostTriple(Opts.HostTriple); if (!HostTriple.isNVPTX()) - HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts)); + HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts); // If no host target, make some guesses about the data layout and return. if (!HostTarget) { @@ -105,12 +93,14 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, default: llvm_unreachable("TargetPointerWidth must be 32 or 64"); } + + MaxAtomicInlineWidth = TargetPointerWidth; return; } // Copy properties from host target. - PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0); - PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0); + PointerWidth = HostTarget->getPointerWidth(LangAS::Default); + PointerAlign = HostTarget->getPointerAlign(LangAS::Default); BoolWidth = HostTarget->getBoolWidth(); BoolAlign = HostTarget->getBoolAlign(); IntWidth = HostTarget->getIntWidth(); @@ -131,7 +121,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, HostTarget->getDefaultAlignForAttributeAligned(); SizeType = HostTarget->getSizeType(); IntMaxType = HostTarget->getIntMaxType(); - PtrDiffType = HostTarget->getPtrDiffType(/* AddrSpace = */ 0); + PtrDiffType = HostTarget->getPtrDiffType(LangAS::Default); IntPtrType = HostTarget->getIntPtrType(); WCharType = HostTarget->getWCharType(); WIntType = HostTarget->getWIntType(); @@ -165,7 +155,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, } ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } bool NVPTXTargetInfo::hasFeature(StringRef Feature) const { @@ -178,7 +168,7 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__PTX__"); Builder.defineMacro("__NVPTX__"); - if (Opts.CUDAIsDevice) { + if (Opts.CUDAIsDevice || Opts.OpenMPIsTargetDevice || !HostTarget) { // Set __CUDA_ARCH__ for the GPU specified. std::string CUDAArchCode = [this] { switch (GPU) { @@ -204,6 +194,9 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, case CudaArch::GFX909: case CudaArch::GFX90a: case CudaArch::GFX90c: + case CudaArch::GFX940: + case CudaArch::GFX941: + case CudaArch::GFX942: case CudaArch::GFX1010: case CudaArch::GFX1011: case CudaArch::GFX1012: @@ -214,6 +207,16 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, case CudaArch::GFX1033: case CudaArch::GFX1034: case CudaArch::GFX1035: + case CudaArch::GFX1036: + case CudaArch::GFX1100: + case CudaArch::GFX1101: + case CudaArch::GFX1102: + case CudaArch::GFX1103: + case CudaArch::GFX1150: + case CudaArch::GFX1151: + case CudaArch::GFX1200: + case CudaArch::GFX1201: + case CudaArch::Generic: case CudaArch::LAST: break; case CudaArch::UNUSED: @@ -254,14 +257,23 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, return "800"; case CudaArch::SM_86: return "860"; + case CudaArch::SM_87: + return "870"; + case CudaArch::SM_89: + return "890"; + case CudaArch::SM_90: + case CudaArch::SM_90a: + return "900"; } llvm_unreachable("unhandled CudaArch"); }(); Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode); + if (GPU == CudaArch::SM_90a) + Builder.defineMacro("__CUDA_ARCH_FEAT_SM90_ALL", "1"); } } ArrayRef<Builtin::Info> NVPTXTargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfo, clang::NVPTX::LastTSBuiltin - - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfo, + clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin); } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.h b/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.h index c7db3cdaaf10..20d76b702a94 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.h @@ -16,8 +16,9 @@ #include "clang/Basic/Cuda.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" +#include <optional> namespace clang { namespace targets { @@ -42,7 +43,11 @@ static const unsigned NVPTXAddrSpaceMap[] = { 0, // sycl_private 0, // ptr32_sptr 0, // ptr32_uptr - 0 // ptr64 + 0, // ptr64 + 0, // hlsl_groupshared + // Wasm address space values for this target are dummy values, + // as it is only enabled for Wasm targets. + 20, // wasm_funcref }; /// The DWARF address class. Taken from @@ -57,7 +62,6 @@ static const int NVPTXDWARFAddrSpaceMap[] = { class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo { static const char *const GCCRegNames[]; - static const Builtin::Info BuiltinInfo[]; CudaArch GPU; uint32_t PTXVersion; std::unique_ptr<TargetInfo> HostTarget; @@ -86,7 +90,7 @@ public: ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { // No aliases. - return None; + return std::nullopt; } bool validateAsmConstraint(const char *&Name, @@ -105,7 +109,7 @@ public: } } - const char *getClobbers() const override { + std::string_view getClobbers() const override { // FIXME: Is this really right? return ""; } @@ -121,7 +125,7 @@ public: void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override { for (int i = static_cast<int>(CudaArch::SM_20); - i < static_cast<int>(CudaArch::LAST); ++i) + i < static_cast<int>(CudaArch::Generic); ++i) Values.emplace_back(CudaArchToString(static_cast<CudaArch>(i))); } @@ -147,17 +151,21 @@ public: Opts["cl_khr_local_int32_extended_atomics"] = true; } + const llvm::omp::GV &getGridValue() const override { + return llvm::omp::NVPTXGridValues; + } + /// \returns If a target requires an address within a target specific address /// space \p AddressSpace to be converted in order to be used, then return the /// corresponding target specific DWARF address space. /// - /// \returns Otherwise return None and no conversion will be emitted in the - /// DWARF. - Optional<unsigned> + /// \returns Otherwise return std::nullopt and no conversion will be emitted + /// in the DWARF. + std::optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace) const override { - if (AddressSpace >= llvm::array_lengthof(NVPTXDWARFAddrSpaceMap) || + if (AddressSpace >= std::size(NVPTXDWARFAddrSpaceMap) || NVPTXDWARFAddrSpaceMap[AddressSpace] < 0) - return llvm::None; + return std::nullopt; return NVPTXDWARFAddrSpaceMap[AddressSpace]; } @@ -171,7 +179,10 @@ public: return CCCR_Warning; } - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } + bool hasBFloat16Type() const override { return true; } + + CudaArch getGPU() const { return GPU; } }; } // namespace targets } // namespace clang diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp index 7cd4a5190120..899aefa6173a 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp @@ -48,12 +48,12 @@ void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, Builder.defineMacro("_REENTRANT"); // Get the platform type and version number from the triple. - unsigned Maj, Min, Rev; + VersionTuple OsVersion; if (Triple.isMacOSX()) { - Triple.getMacOSXVersion(Maj, Min, Rev); + Triple.getMacOSXVersion(OsVersion); PlatformName = "macos"; } else { - Triple.getOSVersion(Maj, Min, Rev); + OsVersion = Triple.getOSVersion(); PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); if (PlatformName == "ios" && Triple.isMacCatalystEnvironment()) PlatformName = "maccatalyst"; @@ -63,78 +63,63 @@ void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, // generating code for Win32 ABI. No need to emit // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__. if (PlatformName == "win32") { - PlatformMinVersion = VersionTuple(Maj, Min, Rev); + PlatformMinVersion = OsVersion; return; } - // Set the appropriate OS version define. - if (Triple.isiOS()) { - assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); - char Str[7]; - if (Maj < 10) { - Str[0] = '0' + Maj; - Str[1] = '0' + (Min / 10); - Str[2] = '0' + (Min % 10); - Str[3] = '0' + (Rev / 10); - Str[4] = '0' + (Rev % 10); - Str[5] = '\0'; - } else { - // Handle versions >= 10. - Str[0] = '0' + (Maj / 10); - Str[1] = '0' + (Maj % 10); - Str[2] = '0' + (Min / 10); - Str[3] = '0' + (Min % 10); - Str[4] = '0' + (Rev / 10); - Str[5] = '0' + (Rev % 10); - Str[6] = '\0'; - } - if (Triple.isTvOS()) - Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str); - else - Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", - Str); + assert(OsVersion < VersionTuple(100) && "Invalid version!"); + char Str[7]; + if (Triple.isMacOSX() && OsVersion < VersionTuple(10, 10)) { + Str[0] = '0' + (OsVersion.getMajor() / 10); + Str[1] = '0' + (OsVersion.getMajor() % 10); + Str[2] = '0' + std::min(OsVersion.getMinor().value_or(0), 9U); + Str[3] = '0' + std::min(OsVersion.getSubminor().value_or(0), 9U); + Str[4] = '\0'; + } else if (!Triple.isMacOSX() && OsVersion.getMajor() < 10) { + Str[0] = '0' + OsVersion.getMajor(); + Str[1] = '0' + (OsVersion.getMinor().value_or(0) / 10); + Str[2] = '0' + (OsVersion.getMinor().value_or(0) % 10); + Str[3] = '0' + (OsVersion.getSubminor().value_or(0) / 10); + Str[4] = '0' + (OsVersion.getSubminor().value_or(0) % 10); + Str[5] = '\0'; + } else { + // Handle versions >= 10. + Str[0] = '0' + (OsVersion.getMajor() / 10); + Str[1] = '0' + (OsVersion.getMajor() % 10); + Str[2] = '0' + (OsVersion.getMinor().value_or(0) / 10); + Str[3] = '0' + (OsVersion.getMinor().value_or(0) % 10); + Str[4] = '0' + (OsVersion.getSubminor().value_or(0) / 10); + Str[5] = '0' + (OsVersion.getSubminor().value_or(0) % 10); + Str[6] = '\0'; + } + // Set the appropriate OS version define. + if (Triple.isTvOS()) { + Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str); + } else if (Triple.isiOS()) { + Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str); } else if (Triple.isWatchOS()) { - assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); - char Str[6]; - Str[0] = '0' + Maj; - Str[1] = '0' + (Min / 10); - Str[2] = '0' + (Min % 10); - Str[3] = '0' + (Rev / 10); - Str[4] = '0' + (Rev % 10); - Str[5] = '\0'; Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str); + } else if (Triple.isDriverKit()) { + assert(OsVersion.getMinor().value_or(0) < 100 && + OsVersion.getSubminor().value_or(0) < 100 && "Invalid version!"); + Builder.defineMacro("__ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__", Str); } else if (Triple.isMacOSX()) { - // Note that the Driver allows versions which aren't representable in the - // define (because we only get a single digit for the minor and micro - // revision numbers). So, we limit them to the maximum representable - // version. - assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); - char Str[7]; - if (Maj < 10 || (Maj == 10 && Min < 10)) { - Str[0] = '0' + (Maj / 10); - Str[1] = '0' + (Maj % 10); - Str[2] = '0' + std::min(Min, 9U); - Str[3] = '0' + std::min(Rev, 9U); - Str[4] = '\0'; - } else { - // Handle versions > 10.9. - Str[0] = '0' + (Maj / 10); - Str[1] = '0' + (Maj % 10); - Str[2] = '0' + (Min / 10); - Str[3] = '0' + (Min % 10); - Str[4] = '0' + (Rev / 10); - Str[5] = '0' + (Rev % 10); - Str[6] = '\0'; - } Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str); } - // Tell users about the kernel if there is one. - if (Triple.isOSDarwin()) + if (Triple.isOSDarwin()) { + // Any darwin OS defines a general darwin OS version macro in addition + // to the other OS specific macros. + assert(OsVersion.getMinor().value_or(0) < 100 && + OsVersion.getSubminor().value_or(0) < 100 && "Invalid version!"); + Builder.defineMacro("__ENVIRONMENT_OS_VERSION_MIN_REQUIRED__", Str); + + // Tell users about the kernel if there is one. Builder.defineMacro("__MACH__"); + } - PlatformMinVersion = VersionTuple(Maj, Min, Rev); + PlatformMinVersion = OsVersion; } static void addMinGWDefines(const llvm::Triple &Triple, const LangOptions &Opts, @@ -165,6 +150,54 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) { if (!Opts.CharIsSigned) Builder.defineMacro("_CHAR_UNSIGNED"); + // "The /fp:contract option allows the compiler to generate floating-point + // contractions [...]" + if (Opts.getDefaultFPContractMode() != LangOptions::FPModeKind::FPM_Off) + Builder.defineMacro("_M_FP_CONTRACT"); + + // "The /fp:except option generates code to ensures that any unmasked + // floating-point exceptions are raised at the exact point at which they + // occur, and that no other floating-point exceptions are raised." + if (Opts.getDefaultExceptionMode() == + LangOptions::FPExceptionModeKind::FPE_Strict) + Builder.defineMacro("_M_FP_EXCEPT"); + + // "The /fp:fast option allows the compiler to reorder, combine, or simplify + // floating-point operations to optimize floating-point code for speed and + // space. The compiler may omit rounding at assignment statements, + // typecasts, or function calls. It may reorder operations or make algebraic + // transforms, for example, by use of associative and distributive laws. It + // may reorder code even if such transformations result in observably + // different rounding behavior." + // + // "Under /fp:precise and /fp:strict, the compiler doesn't do any mathematical + // transformation unless the transformation is guaranteed to produce a bitwise + // identical result." + const bool any_imprecise_flags = + Opts.FastMath || Opts.FiniteMathOnly || Opts.UnsafeFPMath || + Opts.AllowFPReassoc || Opts.NoHonorNaNs || Opts.NoHonorInfs || + Opts.NoSignedZero || Opts.AllowRecip || Opts.ApproxFunc; + + // "Under both /fp:precise and /fp:fast, the compiler generates code intended + // to run in the default floating-point environment." + // + // "[The] default floating point environment [...] sets the rounding mode + // to round to nearest." + if (Opts.getDefaultRoundingMode() == + LangOptions::RoundingMode::NearestTiesToEven) { + if (any_imprecise_flags) { + Builder.defineMacro("_M_FP_FAST"); + } else { + Builder.defineMacro("_M_FP_PRECISE"); + } + } else if (!any_imprecise_flags && Opts.getDefaultRoundingMode() == + LangOptions::RoundingMode::Dynamic) { + // "Under /fp:strict, the compiler generates code that allows the + // program to safely unmask floating-point exceptions, read or write + // floating-point status registers, or change rounding modes." + Builder.defineMacro("_M_FP_STRICT"); + } + // FIXME: POSIXThreads isn't exactly the option this should be defined for, // but it works for now. if (Opts.POSIXThreads) @@ -181,13 +214,19 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) { Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1)); if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) { - if (Opts.CPlusPlus20) - Builder.defineMacro("_MSVC_LANG", "201705L"); + if (Opts.CPlusPlus23) + // TODO update to the proper value. + Builder.defineMacro("_MSVC_LANG", "202004L"); + else if (Opts.CPlusPlus20) + Builder.defineMacro("_MSVC_LANG", "202002L"); else if (Opts.CPlusPlus17) Builder.defineMacro("_MSVC_LANG", "201703L"); else if (Opts.CPlusPlus14) Builder.defineMacro("_MSVC_LANG", "201402L"); } + + if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2022_3)) + Builder.defineMacro("_MSVC_CONSTEXPR_ATTRIBUTE"); } if (Opts.MicrosoftExt) { @@ -200,7 +239,22 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) { } } + if (!Opts.MSVolatile) + Builder.defineMacro("_ISO_VOLATILE"); + + if (Opts.Kernel) + Builder.defineMacro("_KERNEL_MODE"); + Builder.defineMacro("_INTEGRAL_MAX_BITS", "64"); + Builder.defineMacro("__STDC_NO_THREADS__"); + + // Starting with VS 2022 17.1, MSVC predefines the below macro to inform + // users of the execution character set defined at compile time. + // The value given is the Windows Code Page Identifier: + // https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers + // + // Clang currently only supports UTF-8, so we'll use 65001 + Builder.defineMacro("_MSVC_EXECUTION_CHARACTER_SET", "65001"); } void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts, diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h index 3fe39ed64d9c..4366c1149e40 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h @@ -34,42 +34,6 @@ public: } }; -// CloudABI Target -template <typename Target> -class LLVM_LIBRARY_VISIBILITY CloudABITargetInfo : public OSTargetInfo<Target> { -protected: - void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, - MacroBuilder &Builder) const override { - Builder.defineMacro("__CloudABI__"); - Builder.defineMacro("__ELF__"); - - // CloudABI uses ISO/IEC 10646:2012 for wchar_t, char16_t and char32_t. - Builder.defineMacro("__STDC_ISO_10646__", "201206L"); - Builder.defineMacro("__STDC_UTF_16__"); - Builder.defineMacro("__STDC_UTF_32__"); - } - -public: - CloudABITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : OSTargetInfo<Target>(Triple, Opts) {} -}; - -// Ananas target -template <typename Target> -class LLVM_LIBRARY_VISIBILITY AnanasTargetInfo : public OSTargetInfo<Target> { -protected: - void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, - MacroBuilder &Builder) const override { - // Ananas defines - Builder.defineMacro("__Ananas__"); - Builder.defineMacro("__ELF__"); - } - -public: - AnanasTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : OSTargetInfo<Target>(Triple, Opts) {} -}; - void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, const llvm::Triple &Triple, StringRef &PlatformName, VersionTuple &PlatformMinVersion); @@ -108,7 +72,10 @@ public: this->TLSSupported = !Triple.isOSVersionLT(2); else this->TLSSupported = !Triple.isOSVersionLT(3); - } + } else if (Triple.isDriverKit()) { + // No TLS on DriverKit. + } else if (Triple.isXROS()) + this->TLSSupported = true; this->MCountName = "\01mcount"; } @@ -143,14 +110,15 @@ public: case llvm::Triple::WatchOS: // Earliest supporting version is 5.0.0. MinVersion = llvm::VersionTuple(5U); break; + case llvm::Triple::XROS: + MinVersion = llvm::VersionTuple(0); + break; default: // Conservatively return 8 bytes if OS is unknown. return 64; } - unsigned Major, Minor, Micro; - T.getOSVersion(Major, Minor, Micro); - if (llvm::VersionTuple(Major, Minor, Micro) < MinVersion) + if (T.getOSVersion() < MinVersion) return 64; return OSTargetInfo<Target>::getExnObjectAlignment(); } @@ -163,6 +131,10 @@ public: : TargetInfo::UnsignedLongLong) : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned); } + + bool areDefaultedSMFStillPOD(const LangOptions &) const override { + return false; + } }; // DragonFlyBSD Target @@ -175,10 +147,11 @@ protected: // DragonFly defines; list based off of gcc output Builder.defineMacro("__DragonFly__"); Builder.defineMacro("__DragonFly_cc_version", "100001"); - Builder.defineMacro("__ELF__"); Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); Builder.defineMacro("__tune_i386__"); DefineStd(Builder, "unix", Opts); + if (this->HasFloat128) + Builder.defineMacro("__FLOAT128__"); } public: @@ -188,6 +161,7 @@ public: default: case llvm::Triple::x86: case llvm::Triple::x86_64: + this->HasFloat128 = true; this->MCountName = ".mcount"; break; } @@ -217,7 +191,8 @@ protected: Builder.defineMacro("__FreeBSD_cc_version", Twine(CCVersion)); Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); DefineStd(Builder, "unix", Opts); - Builder.defineMacro("__ELF__"); + if (this->HasFloat128) + Builder.defineMacro("__FLOAT128__"); // On FreeBSD, wchar_t contains the number of the code point as // used by the character set of the locale. These character sets are @@ -235,9 +210,11 @@ public: FreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : OSTargetInfo<Target>(Triple, Opts) { switch (Triple.getArch()) { - default: case llvm::Triple::x86: case llvm::Triple::x86_64: + this->HasFloat128 = true; + [[fallthrough]]; + default: this->MCountName = ".mcount"; break; case llvm::Triple::mips: @@ -269,7 +246,6 @@ protected: DefineStd(Builder, "unix", Opts); Builder.defineMacro("__FreeBSD_kernel__"); Builder.defineMacro("__GLIBC__"); - Builder.defineMacro("__ELF__"); if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); if (Opts.CPlusPlus) @@ -277,8 +253,7 @@ protected: } public: - KFreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : OSTargetInfo<Target>(Triple, Opts) {} + using OSTargetInfo<Target>::OSTargetInfo; }; // Haiku Target @@ -289,9 +264,8 @@ protected: MacroBuilder &Builder) const override { // Haiku defines; list based off of gcc output Builder.defineMacro("__HAIKU__"); - Builder.defineMacro("__ELF__"); DefineStd(Builder, "unix", Opts); - if (this->HasFloat128) + if (this->HasFloat128) Builder.defineMacro("__FLOAT128__"); } @@ -302,7 +276,6 @@ public: this->IntPtrType = TargetInfo::SignedLong; this->PtrDiffType = TargetInfo::SignedLong; this->ProcessIDType = TargetInfo::SignedLong; - this->TLSSupported = false; switch (Triple.getArch()) { default: break; @@ -326,39 +299,13 @@ protected: Builder.defineMacro("__gnu_hurd__"); Builder.defineMacro("__MACH__"); Builder.defineMacro("__GLIBC__"); - Builder.defineMacro("__ELF__"); if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); if (Opts.CPlusPlus) Builder.defineMacro("_GNU_SOURCE"); } public: - HurdTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : OSTargetInfo<Target>(Triple, Opts) {} -}; - -// Minix Target -template <typename Target> -class LLVM_LIBRARY_VISIBILITY MinixTargetInfo : public OSTargetInfo<Target> { -protected: - void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, - MacroBuilder &Builder) const override { - // Minix defines - - Builder.defineMacro("__minix", "3"); - Builder.defineMacro("_EM_WSIZE", "4"); - Builder.defineMacro("_EM_PSIZE", "4"); - Builder.defineMacro("_EM_SSIZE", "2"); - Builder.defineMacro("_EM_LSIZE", "4"); - Builder.defineMacro("_EM_FSIZE", "4"); - Builder.defineMacro("_EM_DSIZE", "8"); - Builder.defineMacro("__ELF__"); - DefineStd(Builder, "unix", Opts); - } - -public: - MinixTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : OSTargetInfo<Target>(Triple, Opts) {} + using OSTargetInfo<Target>::OSTargetInfo; }; // Linux target @@ -370,13 +317,11 @@ protected: // Linux defines; list based off of gcc output DefineStd(Builder, "unix", Opts); DefineStd(Builder, "linux", Opts); - Builder.defineMacro("__ELF__"); if (Triple.isAndroid()) { Builder.defineMacro("__ANDROID__", "1"); - unsigned Maj, Min, Rev; - Triple.getEnvironmentVersion(Maj, Min, Rev); this->PlatformName = "android"; - this->PlatformMinVersion = VersionTuple(Maj, Min, Rev); + this->PlatformMinVersion = Triple.getEnvironmentVersion(); + const unsigned Maj = this->PlatformMinVersion.getMajor(); if (Maj) { Builder.defineMacro("__ANDROID_MIN_SDK_VERSION__", Twine(Maj)); // This historical but ambiguous name for the minSdkVersion macro. Keep @@ -433,15 +378,24 @@ protected: // NetBSD defines; list based off of gcc output Builder.defineMacro("__NetBSD__"); Builder.defineMacro("__unix__"); - Builder.defineMacro("__ELF__"); if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); + if (this->HasFloat128) + Builder.defineMacro("__FLOAT128__"); } public: NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : OSTargetInfo<Target>(Triple, Opts) { this->MCountName = "__mcount"; + switch (Triple.getArch()) { + default: + break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->HasFloat128 = true; + break; + } } }; @@ -455,16 +409,13 @@ protected: Builder.defineMacro("__OpenBSD__"); DefineStd(Builder, "unix", Opts); - Builder.defineMacro("__ELF__"); if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); if (this->HasFloat128) Builder.defineMacro("__FLOAT128__"); - if (Opts.C11) { - Builder.defineMacro("__STDC_NO_ATOMICS__"); + if (Opts.C11) Builder.defineMacro("__STDC_NO_THREADS__"); - } } public: @@ -477,7 +428,7 @@ public: case llvm::Triple::x86: case llvm::Triple::x86_64: this->HasFloat128 = true; - LLVM_FALLTHROUGH; + [[fallthrough]]; default: this->MCountName = "__mcount"; break; @@ -496,23 +447,6 @@ public: } }; -// PSP Target -template <typename Target> -class LLVM_LIBRARY_VISIBILITY PSPTargetInfo : public OSTargetInfo<Target> { -protected: - void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, - MacroBuilder &Builder) const override { - // PSP defines; list based on the output of the pspdev gcc toolchain. - Builder.defineMacro("PSP"); - Builder.defineMacro("_PSP"); - Builder.defineMacro("__psp__"); - Builder.defineMacro("__ELF__"); - } - -public: - PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {} -}; - // PS3 PPU Target template <typename Target> class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> { @@ -520,10 +454,8 @@ protected: void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const override { // PS3 PPU defines. - Builder.defineMacro("__PPC__"); Builder.defineMacro("__PPU__"); Builder.defineMacro("__CELLOS_LV2__"); - Builder.defineMacro("__ELF__"); Builder.defineMacro("__LP32__"); Builder.defineMacro("_ARCH_PPC64"); Builder.defineMacro("__powerpc64__"); @@ -537,12 +469,13 @@ public: this->IntMaxType = TargetInfo::SignedLongLong; this->Int64Type = TargetInfo::SignedLongLong; this->SizeType = TargetInfo::UnsignedInt; - this->resetDataLayout("E-m:e-p:32:32-i64:64-n32:64"); + this->resetDataLayout("E-m:e-p:32:32-Fi64-i64:64-n32:64"); } }; +// Common base class for PS4/PS5 targets. template <typename Target> -class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public OSTargetInfo<Target> { +class LLVM_LIBRARY_VISIBILITY PSOSTargetInfo : public OSTargetInfo<Target> { protected: void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const override { @@ -550,35 +483,69 @@ protected: Builder.defineMacro("__FreeBSD_cc_version", "900001"); Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); DefineStd(Builder, "unix", Opts); - Builder.defineMacro("__ELF__"); Builder.defineMacro("__SCE__"); - Builder.defineMacro("__ORBIS__"); + Builder.defineMacro("__STDC_NO_COMPLEX__"); + Builder.defineMacro("__STDC_NO_THREADS__"); } public: - PS4OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + PSOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : OSTargetInfo<Target>(Triple, Opts) { this->WCharType = TargetInfo::UnsignedShort; - // On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits). + // On PS4/PS5, TLS variable cannot be aligned to more than 32 bytes (256 + // bits). this->MaxTLSAlign = 256; - // On PS4, do not honor explicit bit field alignment, + // On PS4/PS5, do not honor explicit bit field alignment, // as in "__attribute__((aligned(2))) int b : 1;". this->UseExplicitBitFieldAlignment = false; - switch (Triple.getArch()) { - default: - case llvm::Triple::x86_64: - this->MCountName = ".mcount"; - this->NewAlign = 256; - break; - } + this->MCountName = ".mcount"; + this->NewAlign = 256; + this->SuitableAlign = 256; } + TargetInfo::CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error; } + + bool areDefaultedSMFStillPOD(const LangOptions &) const override { + return false; + } +}; + +// PS4 Target +template <typename Target> +class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public PSOSTargetInfo<Target> { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + // Start with base class defines. + PSOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder); + + Builder.defineMacro("__ORBIS__"); + } + +public: + using PSOSTargetInfo<Target>::PSOSTargetInfo; +}; + +// PS5 Target +template <typename Target> +class LLVM_LIBRARY_VISIBILITY PS5OSTargetInfo : public PSOSTargetInfo<Target> { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + // Start with base class defines. + PSOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder); + + Builder.defineMacro("__PROSPERO__"); + } + +public: + using PSOSTargetInfo<Target>::PSOSTargetInfo; }; // RTEMS Target @@ -590,7 +557,6 @@ protected: // RTEMS defines; list based off of gcc output Builder.defineMacro("__rtems__"); - Builder.defineMacro("__ELF__"); if (Opts.CPlusPlus) Builder.defineMacro("_GNU_SOURCE"); } @@ -625,7 +591,6 @@ protected: MacroBuilder &Builder) const override { DefineStd(Builder, "sun", Opts); DefineStd(Builder, "unix", Opts); - Builder.defineMacro("__ELF__"); Builder.defineMacro("__svr4__"); Builder.defineMacro("__SVR4"); // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and @@ -678,9 +643,11 @@ protected: DefineStd(Builder, "unix", Opts); Builder.defineMacro("_IBMR2"); Builder.defineMacro("_POWER"); + Builder.defineMacro("__THW_BIG_ENDIAN__"); Builder.defineMacro("_AIX"); Builder.defineMacro("__TOS_AIX__"); + Builder.defineMacro("__HOS_AIX__"); if (Opts.C11) { Builder.defineMacro("__STDC_NO_ATOMICS__"); @@ -690,23 +657,32 @@ protected: if (Opts.EnableAIXExtendedAltivecABI) Builder.defineMacro("__EXTABI__"); - unsigned Major, Minor, Micro; - Triple.getOSVersion(Major, Minor, Micro); + VersionTuple OsVersion = Triple.getOSVersion(); // Define AIX OS-Version Macros. // Includes logic for legacy versions of AIX; no specific intent to support. - std::pair<int, int> OsVersion = {Major, Minor}; - if (OsVersion >= std::make_pair(3, 2)) Builder.defineMacro("_AIX32"); - if (OsVersion >= std::make_pair(4, 1)) Builder.defineMacro("_AIX41"); - if (OsVersion >= std::make_pair(4, 3)) Builder.defineMacro("_AIX43"); - if (OsVersion >= std::make_pair(5, 0)) Builder.defineMacro("_AIX50"); - if (OsVersion >= std::make_pair(5, 1)) Builder.defineMacro("_AIX51"); - if (OsVersion >= std::make_pair(5, 2)) Builder.defineMacro("_AIX52"); - if (OsVersion >= std::make_pair(5, 3)) Builder.defineMacro("_AIX53"); - if (OsVersion >= std::make_pair(6, 1)) Builder.defineMacro("_AIX61"); - if (OsVersion >= std::make_pair(7, 1)) Builder.defineMacro("_AIX71"); - if (OsVersion >= std::make_pair(7, 2)) Builder.defineMacro("_AIX72"); - if (OsVersion >= std::make_pair(7, 3)) Builder.defineMacro("_AIX73"); + if (OsVersion >= VersionTuple(3, 2)) + Builder.defineMacro("_AIX32"); + if (OsVersion >= VersionTuple(4, 1)) + Builder.defineMacro("_AIX41"); + if (OsVersion >= VersionTuple(4, 3)) + Builder.defineMacro("_AIX43"); + if (OsVersion >= VersionTuple(5, 0)) + Builder.defineMacro("_AIX50"); + if (OsVersion >= VersionTuple(5, 1)) + Builder.defineMacro("_AIX51"); + if (OsVersion >= VersionTuple(5, 2)) + Builder.defineMacro("_AIX52"); + if (OsVersion >= VersionTuple(5, 3)) + Builder.defineMacro("_AIX53"); + if (OsVersion >= VersionTuple(6, 1)) + Builder.defineMacro("_AIX61"); + if (OsVersion >= VersionTuple(7, 1)) + Builder.defineMacro("_AIX71"); + if (OsVersion >= VersionTuple(7, 2)) + Builder.defineMacro("_AIX72"); + if (OsVersion >= VersionTuple(7, 3)) + Builder.defineMacro("_AIX73"); // FIXME: Do not define _LONG_LONG when -fno-long-long is specified. Builder.defineMacro("_LONG_LONG"); @@ -729,6 +705,7 @@ protected: public: AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : OSTargetInfo<Target>(Triple, Opts) { + this->MCountName = "__mcount"; this->TheCXXABI.set(TargetCXXABI::XL); if (this->PointerWidth == 64) { @@ -740,10 +717,15 @@ public: } // AIX sets FLT_EVAL_METHOD to be 1. - unsigned getFloatEvalMethod() const override { return 1; } - bool hasInt128Type() const override { return false; } + LangOptions::FPEvalMethodKind getFPEvalMethod() const override { + return LangOptions::FPEvalMethodKind::FEM_Double; + } bool defaultsToAIXPowerAlignment() const override { return true; } + + bool areDefaultedSMFStillPOD(const LangOptions &) const override { + return false; + } }; // z/OS target @@ -754,13 +736,11 @@ protected: MacroBuilder &Builder) const override { // FIXME: _LONG_LONG should not be defined under -std=c89. Builder.defineMacro("_LONG_LONG"); - Builder.defineMacro("_OPEN_DEFAULT"); - // _UNIX03_WITHDRAWN is required to build libcxx. - Builder.defineMacro("_UNIX03_WITHDRAWN"); Builder.defineMacro("__370__"); Builder.defineMacro("__BFP__"); // FIXME: __BOOL__ should not be defined under -std=c89. Builder.defineMacro("__BOOL__"); + Builder.defineMacro("__COMPILER_VER__", "0x50000000"); Builder.defineMacro("__LONGNAME__"); Builder.defineMacro("__MVS__"); Builder.defineMacro("__THW_370__"); @@ -772,17 +752,6 @@ protected: if (this->PointerWidth == 64) Builder.defineMacro("__64BIT__"); - if (Opts.CPlusPlus) { - Builder.defineMacro("__DLL__"); - // _XOPEN_SOURCE=600 is required to build libcxx. - Builder.defineMacro("_XOPEN_SOURCE", "600"); - } - - if (Opts.GNUMode) { - Builder.defineMacro("_MI_BUILTIN"); - Builder.defineMacro("_EXT"); - } - if (Opts.CPlusPlus && Opts.WChar) { // Macro __wchar_t is defined so that the wchar_t data // type is not declared as a typedef in system headers. @@ -801,7 +770,11 @@ public: this->UseZeroLengthBitfieldAlignment = true; this->UseLeadingZeroLengthBitfield = false; this->ZeroLengthBitfieldBoundary = 32; - this->DefaultAlignForAttributeAligned = 128; + this->TheCXXABI.set(TargetCXXABI::XL); + } + + bool areDefaultedSMFStillPOD(const LangOptions &) const override { + return false; } }; @@ -836,7 +809,6 @@ protected: Builder.defineMacro("_GNU_SOURCE"); DefineStd(Builder, "unix", Opts); - Builder.defineMacro("__ELF__"); Builder.defineMacro("__native_client__"); } @@ -863,10 +835,10 @@ public: // Handled in ARM's setABI(). } else if (Triple.getArch() == llvm::Triple::x86) { this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-" - "i64:64-n8:16:32-S128"); + "i64:64-i128:128-n8:16:32-S128"); } else if (Triple.getArch() == llvm::Triple::x86_64) { this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-" - "i64:64-n8:16:32:64-S128"); + "i64:64-i128:128-n8:16:32:64-S128"); } else if (Triple.getArch() == llvm::Triple::mipsel) { // Handled on mips' setDataLayout. } else { @@ -883,12 +855,14 @@ protected: void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const override { Builder.defineMacro("__Fuchsia__"); - Builder.defineMacro("__ELF__"); if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); // Required by the libc++ locale support. if (Opts.CPlusPlus) Builder.defineMacro("_GNU_SOURCE"); + Builder.defineMacro("__Fuchsia_API_level__", Twine(Opts.FuchsiaAPILevel)); + this->PlatformName = "fuchsia"; + this->PlatformMinVersion = VersionTuple(Opts.FuchsiaAPILevel); } public: @@ -937,8 +911,7 @@ class LLVM_LIBRARY_VISIBILITY WASITargetInfo } public: - explicit WASITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {} + using WebAssemblyOSTargetInfo<Target>::WebAssemblyOSTargetInfo; }; // Emscripten target @@ -948,6 +921,7 @@ class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const final { WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder); + DefineStd(Builder, "unix", Opts); Builder.defineMacro("__EMSCRIPTEN__"); if (Opts.POSIXThreads) Builder.defineMacro("__EMSCRIPTEN_PTHREADS__"); @@ -966,6 +940,66 @@ public: } }; +// OHOS target +template <typename Target> +class LLVM_LIBRARY_VISIBILITY OHOSTargetInfo : public OSTargetInfo<Target> { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + // Linux defines; list based off of gcc output + DefineStd(Builder, "unix", Opts); + + // Generic OHOS target defines + if (Triple.isOHOSFamily()) { + Builder.defineMacro("__OHOS_FAMILY__", "1"); + + auto Version = Triple.getEnvironmentVersion(); + this->PlatformName = "ohos"; + this->PlatformMinVersion = Version; + Builder.defineMacro("__OHOS_Major__", Twine(Version.getMajor())); + if (auto Minor = Version.getMinor()) + Builder.defineMacro("__OHOS_Minor__", Twine(*Minor)); + if (auto Subminor = Version.getSubminor()) + Builder.defineMacro("__OHOS_Micro__", Twine(*Subminor)); + } + + if (Triple.isOpenHOS()) + Builder.defineMacro("__OHOS__"); + + if (Triple.isOSLinux()) { + DefineStd(Builder, "linux", Opts); + } else if (Triple.isOSLiteOS()) { + Builder.defineMacro("__LITEOS__"); + } + + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + if (Opts.CPlusPlus) + Builder.defineMacro("_GNU_SOURCE"); + if (this->HasFloat128) + Builder.defineMacro("__FLOAT128__"); + } + +public: + OHOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { + this->WIntType = TargetInfo::UnsignedInt; + + switch (Triple.getArch()) { + default: + break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->HasFloat128 = true; + break; + } + } + + const char *getStaticInitSectionSpecifier() const override { + return ".text.startup"; + } +}; + } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.cpp index 60e9467193a8..51b6452b0c20 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.cpp @@ -16,10 +16,12 @@ using namespace clang; using namespace clang::targets; -ArrayRef<const char *> PNaClTargetInfo::getGCCRegNames() const { return None; } +ArrayRef<const char *> PNaClTargetInfo::getGCCRegNames() const { + return std::nullopt; +} ArrayRef<TargetInfo::GCCRegAlias> PNaClTargetInfo::getGCCRegAliases() const { - return None; + return std::nullopt; } void PNaClTargetInfo::getArchDefines(const LangOptions &Opts, diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.h b/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.h index d5bfc369583f..595c4d83b1d1 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.h @@ -16,8 +16,8 @@ #include "Mips.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { @@ -52,7 +52,9 @@ public: return Feature == "pnacl"; } - ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return std::nullopt; + } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::PNaClABIBuiltinVaList; @@ -67,9 +69,9 @@ public: return false; } - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } }; // We attempt to use PNaCl (le32) frontend and Mips32EL backend. diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp index ecfbe284fb2e..41935abfb65d 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp @@ -18,11 +18,13 @@ using namespace clang; using namespace clang::targets; -const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { +static constexpr Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsPPC.def" }; @@ -36,6 +38,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasAltivec = true; } else if (Feature == "+vsx") { HasVSX = true; + } else if (Feature == "+crbits") { + UseCRBits = true; } else if (Feature == "+bpermd") { HasBPERMD = true; } else if (Feature == "+extdiv") { @@ -49,7 +53,7 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, } else if (Feature == "+htm") { HasHTM = true; } else if (Feature == "+float128") { - HasFloat128 = true; + HasFloat128 = !getTriple().isOSAIX(); } else if (Feature == "+power9-vector") { HasP9Vector = true; } else if (Feature == "+power10-vector") { @@ -73,12 +77,18 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasROPProtect = true; } else if (Feature == "+privileged") { HasPrivileged = true; + } else if (Feature == "+aix-small-local-exec-tls") { + HasAIXSmallLocalExecTLS = true; + } else if (Feature == "+isa-v206-instructions") { + IsISA2_06 = true; } else if (Feature == "+isa-v207-instructions") { IsISA2_07 = true; } else if (Feature == "+isa-v30-instructions") { IsISA3_0 = true; } else if (Feature == "+isa-v31-instructions") { IsISA3_1 = true; + } else if (Feature == "+quadword-atomics") { + HasQuadwordAtomics = true; } // TODO: Finish this list and add an assert that we've handled them // all. @@ -202,8 +212,10 @@ static void defineXLCompatMacros(MacroBuilder &Builder) { Builder.defineMacro("__darn_32", "__builtin_darn_32"); Builder.defineMacro("__darn_raw", "__builtin_darn_raw"); Builder.defineMacro("__dcbf", "__builtin_dcbf"); + Builder.defineMacro("__fence", "__builtin_ppc_fence"); Builder.defineMacro("__fmadd", "__builtin_fma"); Builder.defineMacro("__fmadds", "__builtin_fmaf"); + Builder.defineMacro("__abs", "__builtin_abs"); Builder.defineMacro("__labs", "__builtin_labs"); Builder.defineMacro("__llabs", "__builtin_llabs"); Builder.defineMacro("__popcnt4", "__builtin_popcount"); @@ -236,6 +248,27 @@ static void defineXLCompatMacros(MacroBuilder &Builder) { Builder.defineMacro("__frsqrtes", "__builtin_ppc_frsqrtes"); Builder.defineMacro("__fsqrt", "__builtin_ppc_fsqrt"); Builder.defineMacro("__fsqrts", "__builtin_ppc_fsqrts"); + Builder.defineMacro("__addex", "__builtin_ppc_addex"); + Builder.defineMacro("__cmplxl", "__builtin_complex"); + Builder.defineMacro("__compare_exp_uo", "__builtin_ppc_compare_exp_uo"); + Builder.defineMacro("__compare_exp_lt", "__builtin_ppc_compare_exp_lt"); + Builder.defineMacro("__compare_exp_gt", "__builtin_ppc_compare_exp_gt"); + Builder.defineMacro("__compare_exp_eq", "__builtin_ppc_compare_exp_eq"); + Builder.defineMacro("__test_data_class", "__builtin_ppc_test_data_class"); + Builder.defineMacro("__swdiv", "__builtin_ppc_swdiv"); + Builder.defineMacro("__swdivs", "__builtin_ppc_swdivs"); + Builder.defineMacro("__fnabs", "__builtin_ppc_fnabs"); + Builder.defineMacro("__fnabss", "__builtin_ppc_fnabss"); + Builder.defineMacro("__builtin_maxfe", "__builtin_ppc_maxfe"); + Builder.defineMacro("__builtin_maxfl", "__builtin_ppc_maxfl"); + Builder.defineMacro("__builtin_maxfs", "__builtin_ppc_maxfs"); + Builder.defineMacro("__builtin_minfe", "__builtin_ppc_minfe"); + Builder.defineMacro("__builtin_minfl", "__builtin_ppc_minfl"); + Builder.defineMacro("__builtin_minfs", "__builtin_ppc_minfs"); + Builder.defineMacro("__builtin_mffs", "__builtin_ppc_mffs"); + Builder.defineMacro("__builtin_mffsl", "__builtin_ppc_mffsl"); + Builder.defineMacro("__builtin_mtfsf", "__builtin_ppc_mtfsf"); + Builder.defineMacro("__builtin_set_fpscr_rn", "__builtin_ppc_set_fpscr_rn"); } /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific @@ -257,8 +290,16 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, if (PointerWidth == 64) { Builder.defineMacro("_ARCH_PPC64"); Builder.defineMacro("__powerpc64__"); - Builder.defineMacro("__ppc64__"); Builder.defineMacro("__PPC64__"); + } else if (getTriple().isOSAIX()) { + // The XL compilers on AIX define _ARCH_PPC64 for both 32 and 64-bit modes. + Builder.defineMacro("_ARCH_PPC64"); + } + if (getTriple().isOSAIX()) { + Builder.defineMacro("__THW_PPC__"); + // Define __PPC and __powerpc for AIX XL C/C++ compatibility + Builder.defineMacro("__PPC"); + Builder.defineMacro("__powerpc"); } // Target properties. @@ -304,9 +345,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__LONGDOUBLE64"); } - // Define this for elfv2 (64-bit only) or 64-bit darwin. - if (ABI == "elfv2" || - (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64)) + // Define this for elfv2 (64-bit only). + if (ABI == "elfv2") Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16"); if (ArchDefs & ArchDefineName) @@ -370,8 +410,6 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__MMA__"); if (HasROPProtect) Builder.defineMacro("__ROP_PROTECT__"); - if (HasPrivileged) - Builder.defineMacro("__PRIVILEGED__"); if (HasP10Vector) Builder.defineMacro("__POWER10_VECTOR__"); if (HasPCRelativeMemops) @@ -419,11 +457,11 @@ static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, const std::vector<std::string> &FeaturesVec) { // vsx was not explicitly turned off. - if (llvm::find(FeaturesVec, "-vsx") == FeaturesVec.end()) + if (!llvm::is_contained(FeaturesVec, "-vsx")) return true; auto FindVSXSubfeature = [&](StringRef Feature, StringRef Option) { - if (llvm::find(FeaturesVec, Feature) != FeaturesVec.end()) { + if (llvm::is_contained(FeaturesVec, Feature)) { Diags.Report(diag::err_opt_not_valid_with_opt) << Option << "-mno-vsx"; return true; } @@ -488,6 +526,11 @@ bool PPCTargetInfo::initFeatureMap( .Case("pwr9", true) .Case("pwr8", true) .Default(false); + Features["crbits"] = llvm::StringSwitch<bool>(CPU) + .Case("ppc64le", true) + .Case("pwr9", true) + .Case("pwr8", true) + .Default(false); Features["vsx"] = llvm::StringSwitch<bool>(CPU) .Case("ppc64le", true) .Case("pwr9", true) @@ -505,11 +548,23 @@ bool PPCTargetInfo::initFeatureMap( // Privileged instructions are off by default. Features["privileged"] = false; + // The code generated by the -maix-small-local-exec-tls option is turned + // off by default. + Features["aix-small-local-exec-tls"] = false; + Features["spe"] = llvm::StringSwitch<bool>(CPU) .Case("8548", true) .Case("e500", true) .Default(false); + Features["isa-v206-instructions"] = llvm::StringSwitch<bool>(CPU) + .Case("ppc64le", true) + .Case("pwr9", true) + .Case("pwr8", true) + .Case("pwr7", true) + .Case("a2", true) + .Default(false); + Features["isa-v207-instructions"] = llvm::StringSwitch<bool>(CPU) .Case("ppc64le", true) .Case("pwr9", true) @@ -519,6 +574,12 @@ bool PPCTargetInfo::initFeatureMap( Features["isa-v30-instructions"] = llvm::StringSwitch<bool>(CPU).Case("pwr9", true).Default(false); + Features["quadword-atomics"] = + getTriple().isArch64Bit() && llvm::StringSwitch<bool>(CPU) + .Case("pwr9", true) + .Case("pwr8", true) + .Default(false); + // Power10 includes all the same features as Power9 plus any features specific // to the Power10 core. if (CPU == "pwr10" || CPU == "power10") { @@ -536,33 +597,63 @@ bool PPCTargetInfo::initFeatureMap( if (!ppcUserFeaturesCheck(Diags, FeaturesVec)) return false; - if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr) && - llvm::find(FeaturesVec, "+float128") != FeaturesVec.end()) { - // We have __float128 on PPC but not power 9 and above. + if (!(ArchDefs & ArchDefinePwr7) && (ArchDefs & ArchDefinePpcgr) && + llvm::is_contained(FeaturesVec, "+float128")) { + // We have __float128 on PPC but not pre-VSX targets. Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU; return false; } - if (!(ArchDefs & ArchDefinePwr10) && - llvm::find(FeaturesVec, "+mma") != FeaturesVec.end()) { - // We have MMA on PPC but not power 10 and above. - Diags.Report(diag::err_opt_not_valid_with_opt) << "-mmma" << CPU; - return false; + if (!(ArchDefs & ArchDefinePwr10)) { + if (llvm::is_contained(FeaturesVec, "+mma")) { + // MMA operations are not available pre-Power10. + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mmma" << CPU; + return false; + } + if (llvm::is_contained(FeaturesVec, "+pcrel")) { + // PC-Relative instructions are not available pre-Power10, + // and these instructions also require prefixed instructions support. + Diags.Report(diag::err_opt_not_valid_without_opt) + << "-mpcrel" + << "-mcpu=pwr10 -mprefixed"; + return false; + } + if (llvm::is_contained(FeaturesVec, "+prefixed")) { + // Prefixed instructions are not available pre-Power10. + Diags.Report(diag::err_opt_not_valid_without_opt) << "-mprefixed" + << "-mcpu=pwr10"; + return false; + } + if (llvm::is_contained(FeaturesVec, "+paired-vector-memops")) { + // Paired vector memops are not available pre-Power10. + Diags.Report(diag::err_opt_not_valid_without_opt) + << "-mpaired-vector-memops" + << "-mcpu=pwr10"; + return false; + } } if (!(ArchDefs & ArchDefinePwr8) && - llvm::find(FeaturesVec, "+rop-protect") != FeaturesVec.end()) { + llvm::is_contained(FeaturesVec, "+rop-protect")) { // We can turn on ROP Protect on Power 8 and above. Diags.Report(diag::err_opt_not_valid_with_opt) << "-mrop-protect" << CPU; return false; } if (!(ArchDefs & ArchDefinePwr8) && - llvm::find(FeaturesVec, "+privileged") != FeaturesVec.end()) { + llvm::is_contained(FeaturesVec, "+privileged")) { Diags.Report(diag::err_opt_not_valid_with_opt) << "-mprivileged" << CPU; return false; } + if (llvm::is_contained(FeaturesVec, "+aix-small-local-exec-tls")) { + if (!getTriple().isOSAIX() || !getTriple().isArch64Bit()) { + Diags.Report(diag::err_opt_not_valid_on_target) + << "-maix-small-local-exec-tls"; + return false; + } + } + return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } @@ -576,20 +667,18 @@ void PPCTargetInfo::addP10SpecificFeatures( Features["pcrelative-memops"] = true; Features["prefix-instrs"] = true; Features["isa-v31-instructions"] = true; - return; } // Add features specific to the "Future" CPU. void PPCTargetInfo::addFutureSpecificFeatures( - llvm::StringMap<bool> &Features) const { - return; -} + llvm::StringMap<bool> &Features) const {} bool PPCTargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch<bool>(Feature) .Case("powerpc", true) .Case("altivec", HasAltivec) .Case("vsx", HasVSX) + .Case("crbits", UseCRBits) .Case("power8-vector", HasP8Vector) .Case("crypto", HasP8Crypto) .Case("direct-move", HasDirectMove) @@ -606,9 +695,12 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const { .Case("mma", HasMMA) .Case("rop-protect", HasROPProtect) .Case("privileged", HasPrivileged) + .Case("aix-small-local-exec-tls", HasAIXSmallLocalExecTLS) + .Case("isa-v206-instructions", IsISA2_06) .Case("isa-v207-instructions", IsISA2_07) .Case("isa-v30-instructions", IsISA3_0) .Case("isa-v31-instructions", IsISA3_1) + .Case("quadword-atomics", HasQuadwordAtomics) .Default(false); } @@ -666,6 +758,8 @@ void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, } } +// Make sure that registers are added in the correct array index which should be +// the DWARF number for PPC registers. const char *const PPCTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", @@ -683,41 +777,47 @@ const char *const PPCTargetInfo::GCCRegNames[] = { }; ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { // While some of these aliases do map to different registers // they still share the same register name. - {{"0"}, "r0"}, {{"1"}, "r1"}, {{"2"}, "r2"}, {{"3"}, "r3"}, - {{"4"}, "r4"}, {{"5"}, "r5"}, {{"6"}, "r6"}, {{"7"}, "r7"}, - {{"8"}, "r8"}, {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"}, - {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, {{"15"}, "r15"}, - {{"16"}, "r16"}, {{"17"}, "r17"}, {{"18"}, "r18"}, {{"19"}, "r19"}, - {{"20"}, "r20"}, {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"}, - {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, {{"27"}, "r27"}, - {{"28"}, "r28"}, {{"29"}, "r29"}, {{"30"}, "r30"}, {{"31"}, "r31"}, - {{"fr0"}, "f0"}, {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"}, - {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, {{"fr7"}, "f7"}, - {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, {{"fr10"}, "f10"}, {{"fr11"}, "f11"}, - {{"fr12"}, "f12"}, {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"}, - {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, {{"fr19"}, "f19"}, - {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, {{"fr22"}, "f22"}, {{"fr23"}, "f23"}, - {{"fr24"}, "f24"}, {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"}, - {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, {{"fr31"}, "f31"}, - {{"cc"}, "cr0"}, + {{"0"}, "r0"}, {{"1", "sp"}, "r1"}, {{"2"}, "r2"}, + {{"3"}, "r3"}, {{"4"}, "r4"}, {{"5"}, "r5"}, + {{"6"}, "r6"}, {{"7"}, "r7"}, {{"8"}, "r8"}, + {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"}, + {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, + {{"15"}, "r15"}, {{"16"}, "r16"}, {{"17"}, "r17"}, + {{"18"}, "r18"}, {{"19"}, "r19"}, {{"20"}, "r20"}, + {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"}, + {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, + {{"27"}, "r27"}, {{"28"}, "r28"}, {{"29"}, "r29"}, + {{"30"}, "r30"}, {{"31"}, "r31"}, {{"fr0"}, "f0"}, + {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"}, + {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, + {{"fr7"}, "f7"}, {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, + {{"fr10"}, "f10"}, {{"fr11"}, "f11"}, {{"fr12"}, "f12"}, + {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"}, + {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, + {{"fr19"}, "f19"}, {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, + {{"fr22"}, "f22"}, {{"fr23"}, "f23"}, {{"fr24"}, "f24"}, + {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"}, + {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, + {{"fr31"}, "f31"}, {{"cc"}, "cr0"}, }; ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const { - return llvm::makeArrayRef(GCCRegAliases); + return llvm::ArrayRef(GCCRegAliases); } -// PPC ELFABIv2 DWARF Definitoin "Table 2.26. Mappings of Common Registers". +// PPC ELFABIv2 DWARF Definition "Table 2.26. Mappings of Common Registers". // vs0 ~ vs31 is mapping to 32 - 63, -// vs32 ~ vs63 is mapping to 77 - 108. +// vs32 ~ vs63 is mapping to 77 - 108. +// And this mapping applies to all OSes which run on powerpc. const TargetInfo::AddlRegName GCCAddlRegNames[] = { // Table of additional register names to use in user input. - {{"vs0"}, 32}, {{"vs1"}, 33}, {{"vs2"}, 34}, {{"vs3"}, 35}, + {{"vs0"}, 32}, {{"vs1"}, 33}, {{"vs2"}, 34}, {{"vs3"}, 35}, {{"vs4"}, 36}, {{"vs5"}, 37}, {{"vs6"}, 38}, {{"vs7"}, 39}, {{"vs8"}, 40}, {{"vs9"}, 41}, {{"vs10"}, 42}, {{"vs11"}, 43}, {{"vs12"}, 44}, {{"vs13"}, 45}, {{"vs14"}, 46}, {{"vs15"}, 47}, @@ -736,10 +836,7 @@ const TargetInfo::AddlRegName GCCAddlRegNames[] = { }; ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const { - if (ABI == "elfv2") - return llvm::makeArrayRef(GCCAddlRegNames); - else - return TargetInfo::getGCCAddlRegNames(); + return llvm::ArrayRef(GCCAddlRegNames); } static constexpr llvm::StringLiteral ValidCPUNames[] = { @@ -756,7 +853,7 @@ static constexpr llvm::StringLiteral ValidCPUNames[] = { {"powerpc64le"}, {"ppc64le"}, {"future"}}; bool PPCTargetInfo::isValidCPUName(StringRef Name) const { - return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); + return llvm::is_contained(ValidCPUNames, Name); } void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { @@ -772,9 +869,12 @@ void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { ? &llvm::APFloat::IEEEquad() : &llvm::APFloat::PPCDoubleDouble(); Opts.IEEE128 = 1; + if (getTriple().isOSAIX() && Opts.EnableAIXQuadwordAtomicsABI && + HasQuadwordAtomics) + MaxAtomicInlineWidth = 128; } ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfo, clang::PPC::LastTSBuiltin - - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfo, + clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin); } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h b/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h index 7c14a4eb9410..4d62673ba7fb 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h @@ -16,9 +16,9 @@ #include "OSTargets.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { @@ -50,7 +50,6 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { } ArchDefineTypes; ArchDefineTypes ArchDefs = ArchDefineNone; - static const Builtin::Info BuiltinInfo[]; static const char *const GCCRegNames[]; static const TargetInfo::GCCRegAlias GCCRegAliases[]; std::string CPU; @@ -61,7 +60,9 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { bool HasMMA = false; bool HasROPProtect = false; bool HasPrivileged = false; + bool HasAIXSmallLocalExecTLS = false; bool HasVSX = false; + bool UseCRBits = false; bool HasP8Vector = false; bool HasP8Crypto = false; bool HasDirectMove = false; @@ -74,9 +75,11 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { bool HasP10Vector = false; bool HasPCRelativeMemops = false; bool HasPrefixInstrs = false; + bool IsISA2_06 = false; bool IsISA2_07 = false; bool IsISA3_0 = false; bool IsISA3_1 = false; + bool HasQuadwordAtomics = false; protected: std::string ABI; @@ -85,10 +88,10 @@ public: PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { SuitableAlign = 128; - SimdDefaultAlign = 128; LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); HasStrictFP = true; + HasIbm128 = true; } // Set the language option for altivec based on our value. @@ -195,6 +198,8 @@ public: void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, bool Enabled) const override; + bool supportsTargetAttributeTune() const override { return true; } + ArrayRef<const char *> getGCCRegNames() const override; ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; @@ -212,7 +217,7 @@ public: // Don't use floating point registers on soft float ABI. if (FloatABI == SoftFloat) return false; - LLVM_FALLTHROUGH; + [[fallthrough]]; case 'b': // Base register Info.setAllowsRegister(); break; @@ -291,7 +296,7 @@ public: 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; + [[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) @@ -328,7 +333,7 @@ public: return R; } - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } int getEHDataRegisterNumber(unsigned RegNo) const override { if (RegNo == 0) return 3; @@ -347,8 +352,9 @@ public: : "u9__ieee128"; } const char *getFloat128Mangling() const override { return "u9__ieee128"; } + const char *getIbm128Mangling() const override { return "g"; } - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } bool isSPRegName(StringRef RegName) const override { return RegName.equals("r1") || RegName.equals("x1"); @@ -360,11 +366,11 @@ public: PPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : PPCTargetInfo(Triple, Opts) { if (Triple.isOSAIX()) - resetDataLayout("E-m:a-p:32:32-i64:64-n32"); + resetDataLayout("E-m:a-p:32:32-Fi32-i64:64-n32"); else if (Triple.getArch() == llvm::Triple::ppcle) - resetDataLayout("e-m:e-p:32:32-i64:64-n32"); + resetDataLayout("e-m:e-p:32:32-Fn32-i64:64-n32"); else - resetDataLayout("E-m:e-p:32:32-i64:64-n32"); + resetDataLayout("E-m:e-p:32:32-Fn32-i64:64-n32"); switch (getTriple().getOS()) { case llvm::Triple::Linux: @@ -397,7 +403,7 @@ public: } BuiltinVaListKind getBuiltinVaListKind() const override { - // This is the ELF definition, and is overridden by the Darwin sub-target + // This is the ELF definition return TargetInfo::PowerABIBuiltinVaList; } }; @@ -411,20 +417,27 @@ public: LongWidth = LongAlign = PointerWidth = PointerAlign = 64; IntMaxType = SignedLong; Int64Type = SignedLong; - std::string DataLayout = ""; + std::string DataLayout; if (Triple.isOSAIX()) { // TODO: Set appropriate ABI for AIX platform. - DataLayout = "E-m:a-i64:64-n32:64"; + DataLayout = "E-m:a-Fi64-i64:64-n32:64"; LongDoubleWidth = 64; LongDoubleAlign = DoubleAlign = 32; LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } else if ((Triple.getArch() == llvm::Triple::ppc64le)) { - DataLayout = "e-m:e-i64:64-n32:64"; + DataLayout = "e-m:e-Fn32-i64:64-n32:64"; ABI = "elfv2"; } else { - DataLayout = "E-m:e-i64:64-n32:64"; - ABI = "elfv1"; + DataLayout = "E-m:e"; + if (Triple.isPPC64ELFv2ABI()) { + ABI = "elfv2"; + DataLayout += "-Fn32"; + } else { + ABI = "elfv1"; + DataLayout += "-Fi64"; + } + DataLayout += "-i64:64-n32:64"; } if (Triple.isOSFreeBSD() || Triple.isOSOpenBSD() || Triple.isMusl()) { @@ -436,8 +449,18 @@ public: DataLayout += "-S128-v256:256:256-v512:512:512"; resetDataLayout(DataLayout); - // PPC64 supports atomics up to 8 bytes. - MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + // Newer PPC64 instruction sets support atomics up to 16 bytes. + MaxAtomicPromoteWidth = 128; + // Baseline PPC64 supports inlining atomics up to 8 bytes. + MaxAtomicInlineWidth = 64; + } + + void setMaxAtomicWidth() override { + // For power8 and up, backend is able to inline 16-byte atomic lock free + // code. + // TODO: We should allow AIX to inline quadword atomics in the future. + if (!getTriple().isOSAIX() && hasFeature("quadword-atomics")) + MaxAtomicInlineWidth = 128; } BuiltinVaListKind getBuiltinVaListKind() const override { @@ -465,33 +488,6 @@ public: } }; -class LLVM_LIBRARY_VISIBILITY DarwinPPC32TargetInfo - : public DarwinTargetInfo<PPC32TargetInfo> { -public: - DarwinPPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : DarwinTargetInfo<PPC32TargetInfo>(Triple, Opts) { - HasAlignMac68kSupport = true; - BoolWidth = BoolAlign = 32; // XXX support -mone-byte-bool? - PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726 - LongLongAlign = 32; - resetDataLayout("E-m:o-p:32:32-f64:32:64-n32", "_"); - } - - BuiltinVaListKind getBuiltinVaListKind() const override { - return TargetInfo::CharPtrBuiltinVaList; - } -}; - -class LLVM_LIBRARY_VISIBILITY DarwinPPC64TargetInfo - : public DarwinTargetInfo<PPC64TargetInfo> { -public: - DarwinPPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : DarwinTargetInfo<PPC64TargetInfo>(Triple, Opts) { - HasAlignMac68kSupport = true; - resetDataLayout("E-m:o-i64:64-n32:64", "_"); - } -}; - class LLVM_LIBRARY_VISIBILITY AIXPPC32TargetInfo : public AIXTargetInfo<PPC32TargetInfo> { public: diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp index 9705129b39d8..c71b2e9eeb6c 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp @@ -1,4 +1,4 @@ -//===--- RISCV.cpp - Implement RISCV target feature support ---------------===// +//===--- RISCV.cpp - Implement RISC-V 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. @@ -6,20 +6,24 @@ // //===----------------------------------------------------------------------===// // -// This file implements RISCV TargetInfo objects. +// This file implements RISC-V TargetInfo objects. // //===----------------------------------------------------------------------===// #include "RISCV.h" +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/MacroBuilder.h" #include "clang/Basic/TargetBuiltins.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/TargetParser.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/RISCVTargetParser.h" +#include <optional> using namespace clang; using namespace clang::targets; ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const { + // clang-format off static const char *const GCCRegNames[] = { // Integer registers "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", @@ -37,8 +41,13 @@ ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const { "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", - "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"}; - return llvm::makeArrayRef(GCCRegNames); + "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", + + // CSRs + "fflags", "frm", "vtype", "vl", "vxsat", "vxrm" + }; + // clang-format on + return llvm::ArrayRef(GCCRegNames); } ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const { @@ -59,7 +68,7 @@ ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const { {{"fs4"}, "f20"}, {{"fs5"}, "f21"}, {{"fs6"}, "f22"}, {{"fs7"}, "f23"}, {{"fs8"}, "f24"}, {{"fs9"}, "f25"}, {{"fs10"}, "f26"}, {{"fs11"}, "f27"}, {{"ft8"}, "f28"}, {{"ft9"}, "f29"}, {{"ft10"}, "f30"}, {{"ft11"}, "f31"}}; - return llvm::makeArrayRef(GCCRegAliases); + return llvm::ArrayRef(GCCRegAliases); } bool RISCVTargetInfo::validateAsmConstraint( @@ -105,7 +114,7 @@ std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const { std::string R; switch (*Constraint) { case 'v': - R = std::string("v"); + R = std::string("^") + std::string(Constraint, 2); Constraint += 1; break; default: @@ -115,13 +124,20 @@ std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const { return R; } +static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion) { + return MajorVersion * 1000000 + MinorVersion * 1000; +} + void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { - Builder.defineMacro("__ELF__"); Builder.defineMacro("__riscv"); - bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64; + bool Is64Bit = getTriple().isRISCV64(); Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32"); StringRef CodeModel = getTargetOpts().CodeModel; + unsigned FLen = ISAInfo->getFLen(); + unsigned MinVLen = ISAInfo->getMinVLen(); + unsigned MaxELen = ISAInfo->getMaxELen(); + unsigned MaxELenFp = ISAInfo->getMaxELenFp(); if (CodeModel == "default") CodeModel = "small"; @@ -138,21 +154,28 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, else Builder.defineMacro("__riscv_float_abi_soft"); - if (ABIName == "ilp32e") + if (ABIName == "ilp32e" || ABIName == "lp64e") Builder.defineMacro("__riscv_abi_rve"); Builder.defineMacro("__riscv_arch_test"); - Builder.defineMacro("__riscv_i", "2000000"); - if (HasM) { - Builder.defineMacro("__riscv_m", "2000000"); + for (auto &Extension : ISAInfo->getExtensions()) { + auto ExtName = Extension.first; + auto ExtInfo = Extension.second; + + Builder.defineMacro(Twine("__riscv_", ExtName), + Twine(getVersionValue(ExtInfo.Major, ExtInfo.Minor))); + } + + if (ISAInfo->hasExtension("m") || ISAInfo->hasExtension("zmmul")) Builder.defineMacro("__riscv_mul"); + + if (ISAInfo->hasExtension("m")) { Builder.defineMacro("__riscv_div"); Builder.defineMacro("__riscv_muldiv"); } - if (HasA) { - Builder.defineMacro("__riscv_a", "2000000"); + if (ISAInfo->hasExtension("a")) { Builder.defineMacro("__riscv_atomic"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); @@ -161,218 +184,285 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); } - if (HasF || HasD) { - Builder.defineMacro("__riscv_f", "2000000"); - Builder.defineMacro("__riscv_flen", HasD ? "64" : "32"); + if (FLen) { + Builder.defineMacro("__riscv_flen", Twine(FLen)); Builder.defineMacro("__riscv_fdiv"); Builder.defineMacro("__riscv_fsqrt"); } - if (HasD) - Builder.defineMacro("__riscv_d", "2000000"); - - if (HasC) { - Builder.defineMacro("__riscv_c", "2000000"); - Builder.defineMacro("__riscv_compressed"); + if (MinVLen) { + Builder.defineMacro("__riscv_v_min_vlen", Twine(MinVLen)); + Builder.defineMacro("__riscv_v_elen", Twine(MaxELen)); + Builder.defineMacro("__riscv_v_elen_fp", Twine(MaxELenFp)); } - if (HasB) { - Builder.defineMacro("__riscv_b", "93000"); - Builder.defineMacro("__riscv_bitmanip"); - } + if (ISAInfo->hasExtension("c")) + Builder.defineMacro("__riscv_compressed"); - if (HasV) { - Builder.defineMacro("__riscv_v", "10000"); + if (ISAInfo->hasExtension("zve32x")) { Builder.defineMacro("__riscv_vector"); + // Currently we support the v0.12 RISC-V V intrinsics. + Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(0, 12))); } - if (HasZba) - Builder.defineMacro("__riscv_zba", "93000"); - - if (HasZbb) - Builder.defineMacro("__riscv_zbb", "93000"); - - if (HasZbc) - Builder.defineMacro("__riscv_zbc", "93000"); - - if (HasZbe) - Builder.defineMacro("__riscv_zbe", "93000"); + auto VScale = getVScaleRange(Opts); + if (VScale && VScale->first && VScale->first == VScale->second) + Builder.defineMacro("__riscv_v_fixed_vlen", + Twine(VScale->first * llvm::RISCV::RVVBitsPerBlock)); - if (HasZbf) - Builder.defineMacro("__riscv_zbf", "93000"); - - if (HasZbm) - Builder.defineMacro("__riscv_zbm", "93000"); - - if (HasZbp) - Builder.defineMacro("__riscv_zbp", "93000"); - - if (HasZbproposedc) - Builder.defineMacro("__riscv_zbproposedc", "93000"); - - if (HasZbr) - Builder.defineMacro("__riscv_zbr", "93000"); - - if (HasZbs) - Builder.defineMacro("__riscv_zbs", "93000"); - - if (HasZbt) - Builder.defineMacro("__riscv_zbt", "93000"); - - if (HasZfh) - Builder.defineMacro("__riscv_zfh", "1000"); - - if (HasZvamo) - Builder.defineMacro("__riscv_zvamo", "10000"); + if (FastUnalignedAccess) + Builder.defineMacro("__riscv_misaligned_fast"); + else + Builder.defineMacro("__riscv_misaligned_avoid"); - if (HasZvlsseg) - Builder.defineMacro("__riscv_zvlsseg", "10000"); + if (ISAInfo->hasExtension("e")) { + if (Is64Bit) + Builder.defineMacro("__riscv_64e"); + else + Builder.defineMacro("__riscv_32e"); + } } -const Builtin::Info RISCVTargetInfo::BuiltinInfo[] = { +static constexpr Builtin::Info BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) \ + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#include "clang/Basic/BuiltinsRISCVVector.def" #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsRISCV.def" }; ArrayRef<Builtin::Info> RISCVTargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfo, clang::RISCV::LastTSBuiltin - - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfo, + clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin); } bool RISCVTargetInfo::initFeatureMap( llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeaturesVec) const { - if (getTriple().getArch() == llvm::Triple::riscv64) + unsigned XLen = 32; + + if (getTriple().isRISCV64()) { Features["64bit"] = true; + XLen = 64; + } else { + Features["32bit"] = true; + } + + // If a target attribute specified a full arch string, override all the ISA + // extension target features. + const auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride"); + if (I != FeaturesVec.end()) { + std::vector<std::string> OverrideFeatures(std::next(I), FeaturesVec.end()); + + // Add back any non ISA extension features, e.g. +relax. + auto IsNonISAExtFeature = [](StringRef Feature) { + assert(Feature.size() > 1 && (Feature[0] == '+' || Feature[0] == '-')); + StringRef Ext = Feature.substr(1); // drop the +/- + return !llvm::RISCVISAInfo::isSupportedExtensionFeature(Ext); + }; + llvm::copy_if(llvm::make_range(FeaturesVec.begin(), I), + std::back_inserter(OverrideFeatures), IsNonISAExtFeature); + + return TargetInfo::initFeatureMap(Features, Diags, CPU, OverrideFeatures); + } + + // Otherwise, parse the features and add any implied extensions. + std::vector<std::string> AllFeatures = FeaturesVec; + auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec); + if (!ParseResult) { + std::string Buffer; + llvm::raw_string_ostream OutputErrMsg(Buffer); + handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) { + OutputErrMsg << ErrMsg.getMessage(); + }); + Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str(); + return false; + } - return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); + // Append all features, not just new ones, so we override any negatives. + llvm::append_range(AllFeatures, (*ParseResult)->toFeatures()); + return TargetInfo::initFeatureMap(Features, Diags, CPU, AllFeatures); +} + +std::optional<std::pair<unsigned, unsigned>> +RISCVTargetInfo::getVScaleRange(const LangOptions &LangOpts) const { + // RISCV::RVVBitsPerBlock is 64. + unsigned VScaleMin = ISAInfo->getMinVLen() / llvm::RISCV::RVVBitsPerBlock; + + if (LangOpts.VScaleMin || LangOpts.VScaleMax) { + // Treat Zvl*b as a lower bound on vscale. + VScaleMin = std::max(VScaleMin, LangOpts.VScaleMin); + unsigned VScaleMax = LangOpts.VScaleMax; + if (VScaleMax != 0 && VScaleMax < VScaleMin) + VScaleMax = VScaleMin; + return std::pair<unsigned, unsigned>(VScaleMin ? VScaleMin : 1, VScaleMax); + } + + if (VScaleMin > 0) { + unsigned VScaleMax = ISAInfo->getMaxVLen() / llvm::RISCV::RVVBitsPerBlock; + return std::make_pair(VScaleMin, VScaleMax); + } + + return std::nullopt; } /// Return true if has this feature, need to sync with handleTargetFeatures. bool RISCVTargetInfo::hasFeature(StringRef Feature) const { - bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64; - return llvm::StringSwitch<bool>(Feature) - .Case("riscv", true) - .Case("riscv32", !Is64Bit) - .Case("riscv64", Is64Bit) - .Case("64bit", Is64Bit) - .Case("m", HasM) - .Case("a", HasA) - .Case("f", HasF) - .Case("d", HasD) - .Case("c", HasC) - .Case("experimental-b", HasB) - .Case("experimental-v", HasV) - .Case("experimental-zba", HasZba) - .Case("experimental-zbb", HasZbb) - .Case("experimental-zbc", HasZbc) - .Case("experimental-zbe", HasZbe) - .Case("experimental-zbf", HasZbf) - .Case("experimental-zbm", HasZbm) - .Case("experimental-zbp", HasZbp) - .Case("experimental-zbproposedc", HasZbproposedc) - .Case("experimental-zbr", HasZbr) - .Case("experimental-zbs", HasZbs) - .Case("experimental-zbt", HasZbt) - .Case("experimental-zfh", HasZfh) - .Case("experimental-zvamo", HasZvamo) - .Case("experimental-zvlsseg", HasZvlsseg) - .Default(false); + bool Is64Bit = getTriple().isRISCV64(); + auto Result = llvm::StringSwitch<std::optional<bool>>(Feature) + .Case("riscv", true) + .Case("riscv32", !Is64Bit) + .Case("riscv64", Is64Bit) + .Case("32bit", !Is64Bit) + .Case("64bit", Is64Bit) + .Case("experimental", HasExperimental) + .Default(std::nullopt); + if (Result) + return *Result; + + return ISAInfo->hasExtension(Feature); } /// Perform initialization based on the user configured set of features. bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) { - for (const auto &Feature : Features) { - if (Feature == "+m") - HasM = true; - else if (Feature == "+a") - HasA = true; - else if (Feature == "+f") - HasF = true; - else if (Feature == "+d") - HasD = true; - else if (Feature == "+c") - HasC = true; - else if (Feature == "+experimental-b") - HasB = true; - else if (Feature == "+experimental-v") - HasV = true; - else if (Feature == "+experimental-zba") - HasZba = true; - else if (Feature == "+experimental-zbb") - HasZbb = true; - else if (Feature == "+experimental-zbc") - HasZbc = true; - else if (Feature == "+experimental-zbe") - HasZbe = true; - else if (Feature == "+experimental-zbf") - HasZbf = true; - else if (Feature == "+experimental-zbm") - HasZbm = true; - else if (Feature == "+experimental-zbp") - HasZbp = true; - else if (Feature == "+experimental-zbproposedc") - HasZbproposedc = true; - else if (Feature == "+experimental-zbr") - HasZbr = true; - else if (Feature == "+experimental-zbs") - HasZbs = true; - else if (Feature == "+experimental-zbt") - HasZbt = true; - else if (Feature == "+experimental-zfh") - HasZfh = true; - else if (Feature == "+experimental-zvamo") - HasZvamo = true; - else if (Feature == "+experimental-zvlsseg") - HasZvlsseg = true; + unsigned XLen = getTriple().isArch64Bit() ? 64 : 32; + auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, Features); + if (!ParseResult) { + std::string Buffer; + llvm::raw_string_ostream OutputErrMsg(Buffer); + handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) { + OutputErrMsg << ErrMsg.getMessage(); + }); + Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str(); + return false; + } else { + ISAInfo = std::move(*ParseResult); } - return true; -} + if (ABI.empty()) + ABI = ISAInfo->computeDefaultABI().str(); -bool RISCV32TargetInfo::isValidCPUName(StringRef Name) const { - return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name), - /*Is64Bit=*/false); -} + if (ISAInfo->hasExtension("zfh") || ISAInfo->hasExtension("zhinx")) + HasLegalHalfType = true; -void RISCV32TargetInfo::fillValidCPUList( - SmallVectorImpl<StringRef> &Values) const { - llvm::RISCV::fillValidCPUArchList(Values, false); + FastUnalignedAccess = llvm::is_contained(Features, "+fast-unaligned-access"); + + if (llvm::is_contained(Features, "+experimental")) + HasExperimental = true; + + if (ABI == "ilp32e" && ISAInfo->hasExtension("d")) { + Diags.Report(diag::err_invalid_feature_combination) + << "ILP32E cannot be used with the D ISA extension"; + return false; + } + return true; } -bool RISCV32TargetInfo::isValidTuneCPUName(StringRef Name) const { - return llvm::RISCV::checkTuneCPUKind( - llvm::RISCV::parseTuneCPUKind(Name, false), - /*Is64Bit=*/false); +bool RISCVTargetInfo::isValidCPUName(StringRef Name) const { + bool Is64Bit = getTriple().isArch64Bit(); + return llvm::RISCV::parseCPU(Name, Is64Bit); } -void RISCV32TargetInfo::fillValidTuneCPUList( +void RISCVTargetInfo::fillValidCPUList( SmallVectorImpl<StringRef> &Values) const { - llvm::RISCV::fillValidTuneCPUArchList(Values, false); + bool Is64Bit = getTriple().isArch64Bit(); + llvm::RISCV::fillValidCPUArchList(Values, Is64Bit); } -bool RISCV64TargetInfo::isValidCPUName(StringRef Name) const { - return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name), - /*Is64Bit=*/true); +bool RISCVTargetInfo::isValidTuneCPUName(StringRef Name) const { + bool Is64Bit = getTriple().isArch64Bit(); + return llvm::RISCV::parseTuneCPU(Name, Is64Bit); } -void RISCV64TargetInfo::fillValidCPUList( +void RISCVTargetInfo::fillValidTuneCPUList( SmallVectorImpl<StringRef> &Values) const { - llvm::RISCV::fillValidCPUArchList(Values, true); + bool Is64Bit = getTriple().isArch64Bit(); + llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit); } -bool RISCV64TargetInfo::isValidTuneCPUName(StringRef Name) const { - return llvm::RISCV::checkTuneCPUKind( - llvm::RISCV::parseTuneCPUKind(Name, true), - /*Is64Bit=*/true); +static void handleFullArchString(StringRef FullArchStr, + std::vector<std::string> &Features) { + Features.push_back("__RISCV_TargetAttrNeedOverride"); + auto RII = llvm::RISCVISAInfo::parseArchString( + FullArchStr, /* EnableExperimentalExtension */ true); + if (llvm::errorToBool(RII.takeError())) { + // Forward the invalid FullArchStr. + Features.push_back("+" + FullArchStr.str()); + } else { + // Append a full list of features, including any negative extensions so that + // we override the CPU's features. + std::vector<std::string> FeatStrings = + (*RII)->toFeatures(/* AddAllExtensions */ true); + Features.insert(Features.end(), FeatStrings.begin(), FeatStrings.end()); + } } -void RISCV64TargetInfo::fillValidTuneCPUList( - SmallVectorImpl<StringRef> &Values) const { - llvm::RISCV::fillValidTuneCPUArchList(Values, true); +ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const { + ParsedTargetAttr Ret; + if (Features == "default") + return Ret; + SmallVector<StringRef, 1> AttrFeatures; + Features.split(AttrFeatures, ";"); + bool FoundArch = false; + + for (auto &Feature : AttrFeatures) { + Feature = Feature.trim(); + StringRef AttrString = Feature.split("=").second.trim(); + + if (Feature.starts_with("arch=")) { + // Override last features + Ret.Features.clear(); + if (FoundArch) + Ret.Duplicate = "arch="; + FoundArch = true; + + if (AttrString.starts_with("+")) { + // EXTENSION like arch=+v,+zbb + SmallVector<StringRef, 1> Exts; + AttrString.split(Exts, ","); + for (auto Ext : Exts) { + if (Ext.empty()) + continue; + + StringRef ExtName = Ext.substr(1); + std::string TargetFeature = + llvm::RISCVISAInfo::getTargetFeatureForExtension(ExtName); + if (!TargetFeature.empty()) + Ret.Features.push_back(Ext.front() + TargetFeature); + else + Ret.Features.push_back(Ext.str()); + } + } else { + // full-arch-string like arch=rv64gcv + handleFullArchString(AttrString, Ret.Features); + } + } else if (Feature.starts_with("cpu=")) { + if (!Ret.CPU.empty()) + Ret.Duplicate = "cpu="; + + Ret.CPU = AttrString; + + if (!FoundArch) { + // Update Features with CPU's features + StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu(Ret.CPU); + if (MarchFromCPU != "") { + Ret.Features.clear(); + handleFullArchString(MarchFromCPU, Ret.Features); + } + } + } else if (Feature.starts_with("tune=")) { + if (!Ret.Tune.empty()) + Ret.Duplicate = "tune="; + + Ret.Tune = AttrString; + } + } + return Ret; } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h index 7e0846581ca1..bfbdafb682c8 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h @@ -1,4 +1,4 @@ -//===--- RISCV.h - Declare RISCV target feature support ---------*- C++ -*-===// +//===--- RISCV.h - Declare RISC-V 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. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file declares RISCV TargetInfo objects. +// This file declares RISC-V TargetInfo objects. // //===----------------------------------------------------------------------===// @@ -15,8 +15,10 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/RISCVISAInfo.h" +#include "llvm/TargetParser/Triple.h" +#include <optional> namespace clang { namespace targets { @@ -25,33 +27,18 @@ namespace targets { class RISCVTargetInfo : public TargetInfo { protected: std::string ABI, CPU; - bool HasM = false; - bool HasA = false; - bool HasF = false; - bool HasD = false; - bool HasC = false; - bool HasB = false; - bool HasV = false; - bool HasZba = false; - bool HasZbb = false; - bool HasZbc = false; - bool HasZbe = false; - bool HasZbf = false; - bool HasZbm = false; - bool HasZbp = false; - bool HasZbproposedc = false; - bool HasZbr = false; - bool HasZbs = false; - bool HasZbt = false; - bool HasZfh = false; - bool HasZvamo = false; - bool HasZvlsseg = false; - - static const Builtin::Info BuiltinInfo[]; + std::unique_ptr<llvm::RISCVISAInfo> ISAInfo; + +private: + bool FastUnalignedAccess; + bool HasExperimental = false; public: RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { + BFloat16Width = 16; + BFloat16Align = 16; + BFloat16Format = &llvm::APFloat::BFloat(); LongDoubleWidth = 128; LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad(); @@ -61,6 +48,7 @@ public: HasRISCVVTypes = true; MCountName = "_mcount"; HasFloat16 = true; + HasStrictFP = true; } bool setCPU(const std::string &Name) override { @@ -80,7 +68,12 @@ public: return TargetInfo::VoidPtrBuiltinVaList; } - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } + + StringRef getConstraintRegister(StringRef Constraint, + StringRef Expression) const override { + return Expression; + } ArrayRef<const char *> getGCCRegNames() const override; @@ -105,12 +98,28 @@ public: StringRef CPU, const std::vector<std::string> &FeaturesVec) const override; + std::optional<std::pair<unsigned, unsigned>> + getVScaleRange(const LangOptions &LangOpts) const override; + bool hasFeature(StringRef Feature) const override; bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override; - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } + + bool hasBFloat16Type() const override { return true; } + + bool useFP16ConversionIntrinsics() const override { + return false; + } + + bool isValidCPUName(StringRef Name) const override; + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; + bool isValidTuneCPUName(StringRef Name) const override; + void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override; + bool supportsTargetAttributeTune() const override { return true; } + ParsedTargetAttr parseTargetAttr(StringRef Str) const override; }; class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo { public: @@ -123,6 +132,12 @@ public: } bool setABI(const std::string &Name) override { + if (Name == "ilp32e") { + ABI = Name; + resetDataLayout("e-m:e-p:32:32-i64:64-n32-S32"); + return true; + } + if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") { ABI = Name; return true; @@ -130,15 +145,10 @@ public: return false; } - bool isValidCPUName(StringRef Name) const override; - void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; - bool isValidTuneCPUName(StringRef Name) const override; - void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override; - void setMaxAtomicWidth() override { MaxAtomicPromoteWidth = 128; - if (HasA) + if (ISAInfo->hasExtension("a")) MaxAtomicInlineWidth = 32; } }; @@ -148,10 +158,16 @@ public: : RISCVTargetInfo(Triple, Opts) { LongWidth = LongAlign = PointerWidth = PointerAlign = 64; IntMaxType = Int64Type = SignedLong; - resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n64-S128"); + resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"); } bool setABI(const std::string &Name) override { + if (Name == "lp64e") { + ABI = Name; + resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S64"); + return true; + } + if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") { ABI = Name; return true; @@ -159,15 +175,10 @@ public: return false; } - bool isValidCPUName(StringRef Name) const override; - void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; - bool isValidTuneCPUName(StringRef Name) const override; - void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override; - void setMaxAtomicWidth() override { MaxAtomicPromoteWidth = 128; - if (HasA) + if (ISAInfo->hasExtension("a")) MaxAtomicInlineWidth = 64; } }; diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.cpp index 9b7aab85314a..dc920177d3a9 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.cpp @@ -1,4 +1,4 @@ -//===--- SPIR.cpp - Implement SPIR target feature support -----------------===// +//===--- SPIR.cpp - Implement SPIR and SPIR-V 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. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements SPIR TargetInfo objects. +// This file implements SPIR and SPIR-V TargetInfo objects. // //===----------------------------------------------------------------------===// @@ -32,3 +32,25 @@ void SPIR64TargetInfo::getTargetDefines(const LangOptions &Opts, SPIRTargetInfo::getTargetDefines(Opts, Builder); DefineStd(Builder, "SPIR64", Opts); } + +void BaseSPIRVTargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + DefineStd(Builder, "SPIRV", Opts); +} + +void SPIRVTargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder); +} + +void SPIRV32TargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder); + DefineStd(Builder, "SPIRV32", Opts); +} + +void SPIRV64TargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder); + DefineStd(Builder, "SPIRV64", Opts); +} diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h index 50f34abd6630..fa4a3bb1c82e 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h @@ -1,4 +1,4 @@ -//===--- SPIR.h - Declare SPIR target feature support -----------*- C++ -*-===// +//===--- SPIR.h - Declare SPIR and SPIR-V 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. @@ -6,21 +6,25 @@ // //===----------------------------------------------------------------------===// // -// This file declares SPIR TargetInfo objects. +// This file declares SPIR and SPIR-V TargetInfo objects. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H #define LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H +#include "Targets.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/VersionTuple.h" +#include "llvm/TargetParser/Triple.h" +#include <optional> namespace clang { namespace targets { +// Used by both the SPIR and SPIR-V targets. static const unsigned SPIRDefIsPrivMap[] = { 0, // Default 1, // opencl_global @@ -41,9 +45,14 @@ static const unsigned SPIRDefIsPrivMap[] = { 0, // sycl_private 0, // ptr32_sptr 0, // ptr32_uptr - 0 // ptr64 + 0, // ptr64 + 0, // hlsl_groupshared + // Wasm address space values for this target are dummy values, + // as it is only enabled for Wasm targets. + 20, // wasm_funcref }; +// Used by both the SPIR and SPIR-V targets. static const unsigned SPIRDefIsGenMap[] = { 4, // Default // OpenCL address space values for this map are dummy and they can't be used @@ -54,9 +63,14 @@ static const unsigned SPIRDefIsGenMap[] = { 0, // opencl_generic 0, // opencl_global_device 0, // opencl_global_host - 0, // cuda_device - 0, // cuda_constant - 0, // cuda_shared + // cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V + // translation). This mapping is enabled when the language mode is HIP. + 1, // cuda_device + // cuda_constant pointer can be casted to default/"flat" pointer, but in + // SPIR-V casts between constant and generic pointers are not allowed. For + // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup. + 1, // cuda_constant + 3, // cuda_shared 1, // sycl_global 5, // sycl_global_device 6, // sycl_global_host @@ -64,17 +78,22 @@ static const unsigned SPIRDefIsGenMap[] = { 0, // sycl_private 0, // ptr32_sptr 0, // ptr32_uptr - 0 // ptr64 + 0, // ptr64 + 0, // hlsl_groupshared + // Wasm address space values for this target are dummy values, + // as it is only enabled for Wasm targets. + 20, // wasm_funcref }; -class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo { -public: - SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &) +// Base class for SPIR and SPIR-V target info. +class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo { + std::unique_ptr<TargetInfo> HostTarget; + +protected: + BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple) { - assert(getTriple().getOS() == llvm::Triple::UnknownOS && - "SPIR target must use unknown OS"); - assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && - "SPIR target must use unknown environment type"); + assert((Triple.isSPIR() || Triple.isSPIRV()) && + "Invalid architecture for SPIR or SPIR-V."); TLSSupported = false; VLASupported = false; LongWidth = LongAlign = 64; @@ -85,24 +104,68 @@ public: // Define available target features // These must be defined in sorted order! NoAsmVariants = true; - } - void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const override; + llvm::Triple HostTriple(Opts.HostTriple); + if (!HostTriple.isSPIR() && !HostTriple.isSPIRV() && + HostTriple.getArch() != llvm::Triple::UnknownArch) { + HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts); - bool hasFeature(StringRef Feature) const override { - return Feature == "spir"; + // Copy properties from host target. + BoolWidth = HostTarget->getBoolWidth(); + BoolAlign = HostTarget->getBoolAlign(); + IntWidth = HostTarget->getIntWidth(); + IntAlign = HostTarget->getIntAlign(); + HalfWidth = HostTarget->getHalfWidth(); + HalfAlign = HostTarget->getHalfAlign(); + FloatWidth = HostTarget->getFloatWidth(); + FloatAlign = HostTarget->getFloatAlign(); + DoubleWidth = HostTarget->getDoubleWidth(); + DoubleAlign = HostTarget->getDoubleAlign(); + LongWidth = HostTarget->getLongWidth(); + LongAlign = HostTarget->getLongAlign(); + LongLongWidth = HostTarget->getLongLongWidth(); + LongLongAlign = HostTarget->getLongLongAlign(); + MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0); + NewAlign = HostTarget->getNewAlign(); + DefaultAlignForAttributeAligned = + HostTarget->getDefaultAlignForAttributeAligned(); + IntMaxType = HostTarget->getIntMaxType(); + WCharType = HostTarget->getWCharType(); + WIntType = HostTarget->getWIntType(); + Char16Type = HostTarget->getChar16Type(); + Char32Type = HostTarget->getChar32Type(); + Int64Type = HostTarget->getInt64Type(); + SigAtomicType = HostTarget->getSigAtomicType(); + ProcessIDType = HostTarget->getProcessIDType(); + + UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment(); + UseZeroLengthBitfieldAlignment = + HostTarget->useZeroLengthBitfieldAlignment(); + UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment(); + ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary(); + + // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and + // we need those macros to be identical on host and device, because (among + // other things) they affect which standard library classes are defined, + // and we need all classes to be defined on both the host and device. + MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth(); + } } +public: // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is // memcpy as per section 3 of the SPIR spec. bool useFP16ConversionIntrinsics() const override { return false; } - ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return std::nullopt; + } - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } - ArrayRef<const char *> getGCCRegNames() const override { return None; } + ArrayRef<const char *> getGCCRegNames() const override { + return std::nullopt; + } bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override { @@ -110,14 +173,14 @@ public: } ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { - return None; + return std::nullopt; } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; } - Optional<unsigned> + std::optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace) const override { return AddressSpace; } @@ -140,28 +203,56 @@ public: // FIXME: SYCL specification considers unannotated pointers and references // to be pointing to the generic address space. See section 5.9.3 of // SYCL 2020 specification. - // Currently, there is no way of representing SYCL's default address space - // language semantic along with the semantics of embedded C's default - // address space in the same address space map. Hence the map needs to be - // reset to allow mapping to the desired value of 'Default' entry for SYCL. - setAddressSpaceMap(/*DefaultIsGeneric=*/Opts.SYCLIsDevice); + // Currently, there is no way of representing SYCL's and HIP/CUDA's default + // address space language semantic along with the semantics of embedded C's + // default address space in the same address space map. Hence the map needs + // to be reset to allow mapping to the desired value of 'Default' entry for + // SYCL and HIP/CUDA. + setAddressSpaceMap( + /*DefaultIsGeneric=*/Opts.SYCLIsDevice || + // The address mapping from HIP/CUDA language for device code is only + // defined for SPIR-V. + (getTriple().isSPIRV() && Opts.CUDAIsDevice)); } void setSupportedOpenCLOpts() override { // Assume all OpenCL extensions and optional core features are supported - // for SPIR since it is a generic target. + // for SPIR and SPIR-V since they are generic targets. supportAllOpenCLOpts(); } - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } bool hasInt128Type() const override { return false; } }; +class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo { +public: + SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : BaseSPIRTargetInfo(Triple, Opts) { + assert(Triple.isSPIR() && "Invalid architecture for SPIR."); + assert(getTriple().getOS() == llvm::Triple::UnknownOS && + "SPIR target must use unknown OS"); + assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && + "SPIR target must use unknown environment type"); + } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; + + bool hasFeature(StringRef Feature) const override { + return Feature == "spir"; + } + + bool checkArithmeticFenceSupported() const override { return true; } +}; + class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo { public: SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : SPIRTargetInfo(Triple, Opts) { + assert(Triple.getArch() == llvm::Triple::spir && + "Invalid architecture for 32-bit SPIR."); PointerWidth = PointerAlign = 32; SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; @@ -177,6 +268,8 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo { public: SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : SPIRTargetInfo(Triple, Opts) { + assert(Triple.getArch() == llvm::Triple::spir64 && + "Invalid architecture for 64-bit SPIR."); PointerWidth = PointerAlign = 64; SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; @@ -187,6 +280,87 @@ public: void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; }; + +class LLVM_LIBRARY_VISIBILITY BaseSPIRVTargetInfo : public BaseSPIRTargetInfo { +public: + BaseSPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : BaseSPIRTargetInfo(Triple, Opts) { + assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V."); + } + + bool hasFeature(StringRef Feature) const override { + return Feature == "spirv"; + } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; +}; + +class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo { +public: + SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : BaseSPIRVTargetInfo(Triple, Opts) { + assert(Triple.getArch() == llvm::Triple::spirv && + "Invalid architecture for Logical SPIR-V."); + assert(Triple.getOS() == llvm::Triple::Vulkan && + Triple.getVulkanVersion() != llvm::VersionTuple(0) && + "Logical SPIR-V requires a valid Vulkan environment."); + assert(Triple.getEnvironment() >= llvm::Triple::Pixel && + Triple.getEnvironment() <= llvm::Triple::Amplification && + "Logical SPIR-V environment must be a valid shader stage."); + + // SPIR-V IDs are represented with a single 32-bit word. + SizeType = TargetInfo::UnsignedInt; + resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-" + "v96:128-v192:256-v256:256-v512:512-v1024:1024"); + } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; +}; + +class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo { +public: + SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : BaseSPIRVTargetInfo(Triple, Opts) { + assert(Triple.getArch() == llvm::Triple::spirv32 && + "Invalid architecture for 32-bit SPIR-V."); + assert(getTriple().getOS() == llvm::Triple::UnknownOS && + "32-bit SPIR-V target must use unknown OS"); + assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && + "32-bit SPIR-V target must use unknown environment type"); + PointerWidth = PointerAlign = 32; + SizeType = TargetInfo::UnsignedInt; + PtrDiffType = IntPtrType = TargetInfo::SignedInt; + resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-" + "v96:128-v192:256-v256:256-v512:512-v1024:1024"); + } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; +}; + +class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo { +public: + SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : BaseSPIRVTargetInfo(Triple, Opts) { + assert(Triple.getArch() == llvm::Triple::spirv64 && + "Invalid architecture for 64-bit SPIR-V."); + assert(getTriple().getOS() == llvm::Triple::UnknownOS && + "64-bit SPIR-V target must use unknown OS"); + assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && + "64-bit SPIR-V target must use unknown environment type"); + PointerWidth = PointerAlign = 64; + SizeType = TargetInfo::UnsignedLong; + PtrDiffType = IntPtrType = TargetInfo::SignedLong; + resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-" + "v96:128-v192:256-v256:256-v512:512-v1024:1024"); + } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; +}; + } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp index 5eeb77406c34..d1a891092b0f 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp @@ -33,7 +33,7 @@ const char *const SparcTargetInfo::GCCRegNames[] = { }; ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = { @@ -48,7 +48,7 @@ const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = { }; ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const { - return llvm::makeArrayRef(GCCRegAliases); + return llvm::ArrayRef(GCCRegAliases); } bool SparcTargetInfo::hasFeature(StringRef Feature) const { @@ -93,12 +93,6 @@ static constexpr SparcCPUInfo CPUInfo[] = { {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8}, {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8}, {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8}, - // FIXME: the myriad2[.n] spellings are obsolete, - // but a grace period is needed to allow updating dependent builds. - {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, - {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8}, - {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, - {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8}, {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8}, {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8}, {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8}, @@ -147,7 +141,7 @@ void SparcTargetInfo::getTargetDefines(const LangOptions &Opts, void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { SparcTargetInfo::getTargetDefines(Opts, Builder); - if (getTriple().getOS() == llvm::Triple::Solaris) + if (getTriple().isOSSolaris()) Builder.defineMacro("__sparcv8"); else { switch (getCPUGeneration(CPU)) { @@ -156,78 +150,10 @@ void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__sparcv8__"); break; case CG_V9: - Builder.defineMacro("__sparcv9"); - Builder.defineMacro("__sparcv9__"); Builder.defineMacro("__sparc_v9__"); break; } } - if (getTriple().getVendor() == llvm::Triple::Myriad) { - std::string MyriadArchValue, Myriad2Value; - Builder.defineMacro("__sparc_v8__"); - Builder.defineMacro("__leon__"); - switch (CPU) { - case CK_MYRIAD2100: - MyriadArchValue = "__ma2100"; - Myriad2Value = "1"; - break; - case CK_MYRIAD2150: - MyriadArchValue = "__ma2150"; - Myriad2Value = "2"; - break; - case CK_MYRIAD2155: - MyriadArchValue = "__ma2155"; - Myriad2Value = "2"; - break; - case CK_MYRIAD2450: - MyriadArchValue = "__ma2450"; - Myriad2Value = "2"; - break; - case CK_MYRIAD2455: - MyriadArchValue = "__ma2455"; - Myriad2Value = "2"; - break; - case CK_MYRIAD2x5x: - Myriad2Value = "2"; - break; - case CK_MYRIAD2080: - MyriadArchValue = "__ma2080"; - Myriad2Value = "3"; - break; - case CK_MYRIAD2085: - MyriadArchValue = "__ma2085"; - Myriad2Value = "3"; - break; - case CK_MYRIAD2480: - MyriadArchValue = "__ma2480"; - Myriad2Value = "3"; - break; - case CK_MYRIAD2485: - MyriadArchValue = "__ma2485"; - Myriad2Value = "3"; - break; - case CK_MYRIAD2x8x: - Myriad2Value = "3"; - break; - default: - MyriadArchValue = "__ma2100"; - Myriad2Value = "1"; - break; - } - if (!MyriadArchValue.empty()) { - Builder.defineMacro(MyriadArchValue, "1"); - Builder.defineMacro(MyriadArchValue + "__", "1"); - } - if (Myriad2Value == "2") { - Builder.defineMacro("__ma2x5x", "1"); - Builder.defineMacro("__ma2x5x__", "1"); - } else if (Myriad2Value == "3") { - Builder.defineMacro("__ma2x8x", "1"); - Builder.defineMacro("__ma2x8x__", "1"); - } - Builder.defineMacro("__myriad2__", Myriad2Value); - Builder.defineMacro("__myriad2", Myriad2Value); - } if (getCPUGeneration(CPU) == CG_V9) { Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); @@ -242,7 +168,7 @@ void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__sparcv9"); Builder.defineMacro("__arch64__"); // Solaris doesn't need these variants, but the BSDs do. - if (getTriple().getOS() != llvm::Triple::Solaris) { + if (!getTriple().isOSSolaris()) { Builder.defineMacro("__sparc64__"); Builder.defineMacro("__sparc_v9__"); Builder.defineMacro("__sparcv9__"); diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.h b/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.h index 07844abafe11..214fef88e1dc 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.h @@ -14,8 +14,8 @@ #define LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { // Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit). @@ -39,10 +39,8 @@ public: bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override { // Check if software floating point is enabled - auto Feature = llvm::find(Features, "+soft-float"); - if (Feature != Features.end()) { + if (llvm::is_contained(Features, "+soft-float")) SoftFloat = true; - } return true; } void getTargetDefines(const LangOptions &Opts, @@ -50,11 +48,9 @@ public: bool hasFeature(StringRef Feature) const override; - bool hasSjLjLowering() const override { return true; } - ArrayRef<Builtin::Info> getTargetBuiltins() const override { // FIXME: Implement! - return None; + return std::nullopt; } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; @@ -81,7 +77,7 @@ public: } return false; } - const char *getClobbers() const override { + std::string_view getClobbers() const override { // FIXME: Implement! return ""; } @@ -180,8 +176,7 @@ public: void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - bool hasSjLjLowering() const override { return true; } - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } }; // SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel. @@ -234,7 +229,7 @@ public: return getCPUGeneration(CPU) == CG_V9; } - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } }; } // namespace targets } // namespace clang diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.cpp index e3e0da21f8d5..a9b5ca483861 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.cpp @@ -20,11 +20,11 @@ using namespace clang; using namespace clang::targets; -const Builtin::Info SystemZTargetInfo::BuiltinInfo[] = { +static constexpr Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsSystemZ.def" }; @@ -46,11 +46,11 @@ const TargetInfo::AddlRegName GCCAddlRegNames[] = { }; ArrayRef<const char *> SystemZTargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } ArrayRef<TargetInfo::AddlRegName> SystemZTargetInfo::getGCCAddlRegNames() const { - return llvm::makeArrayRef(GCCAddlRegNames); + return llvm::ArrayRef(GCCAddlRegNames); } bool SystemZTargetInfo::validateAsmConstraint( @@ -59,6 +59,17 @@ bool SystemZTargetInfo::validateAsmConstraint( default: return false; + case 'Z': + switch (Name[1]) { + default: + return false; + case 'Q': // Address with base and unsigned 12-bit displacement + case 'R': // Likewise, plus an index + case 'S': // Address with base and signed 20-bit displacement + case 'T': // Likewise, plus an index + break; + } + [[fallthrough]]; case 'a': // Address register case 'd': // Data register (equivalent to 'r') case 'f': // Floating-point register @@ -93,7 +104,7 @@ static constexpr ISANameRevision ISARevisions[] = { {{"arch11"}, 11}, {{"z13"}, 11}, {{"arch12"}, 12}, {{"z14"}, 12}, {{"arch13"}, 13}, {{"z15"}, 13}, - {{"arch14"}, 14} + {{"arch14"}, 14}, {{"z16"}, 14}, }; int SystemZTargetInfo::getISARevision(StringRef Name) const { @@ -150,6 +161,6 @@ void SystemZTargetInfo::getTargetDefines(const LangOptions &Opts, } ArrayRef<Builtin::Info> SystemZTargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfo, clang::SystemZ::LastTSBuiltin - - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfo, clang::SystemZ::LastTSBuiltin - + Builtin::FirstTSBuiltin); } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.h b/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.h index b749c3f75d18..e4ec338880f2 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.h @@ -15,15 +15,14 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { - static const Builtin::Info BuiltinInfo[]; static const char *const GCCRegNames[]; std::string CPU; int ISARevision; @@ -37,17 +36,31 @@ public: HasTransactionalExecution(false), HasVector(false), SoftFloat(false) { IntMaxType = SignedLong; Int64Type = SignedLong; - TLSSupported = true; IntWidth = IntAlign = 32; LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; + Int128Align = 64; PointerWidth = PointerAlign = 64; LongDoubleWidth = 128; LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEquad(); DefaultAlignForAttributeAligned = 64; MinGlobalAlign = 16; - resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); - MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + if (Triple.isOSzOS()) { + TLSSupported = false; + // All vector types are default aligned on an 8-byte boundary, even if the + // vector facility is not available. That is different from Linux. + MaxVectorAlign = 64; + // Compared to Linux/ELF, the data layout differs only in some details: + // - name mangling is GOFF. + // - 32 bit pointers, either as default or special address space + resetDataLayout("E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-" + "a:8:16-n32:64"); + } else { + TLSSupported = true; + resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" + "-v128:64-a:8:16-n32:64"); + } + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128; HasStrictFP = true; } @@ -60,7 +73,7 @@ public: ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { // No aliases. - return None; + return std::nullopt; } ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; @@ -72,7 +85,31 @@ public: bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override; - const char *getClobbers() const override { + std::string convertConstraint(const char *&Constraint) const override { + switch (Constraint[0]) { + case 'p': // Keep 'p' constraint. + return std::string("p"); + case 'Z': + switch (Constraint[1]) { + case 'Q': // Address with base and unsigned 12-bit displacement + case 'R': // Likewise, plus an index + case 'S': // Address with base and signed 20-bit displacement + case 'T': // Likewise, plus an index + // "^" hints llvm that this is a 2 letter constraint. + // "Constraint++" is used to promote the string iterator + // to the next constraint. + return std::string("^") + std::string(Constraint++, 2); + default: + break; + } + break; + default: + break; + } + return TargetInfo::convertConstraint(Constraint); + } + + std::string_view getClobbers() const override { // FIXME: Is this really right? return ""; } @@ -89,6 +126,14 @@ public: void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; + bool isValidTuneCPUName(StringRef Name) const override { + return isValidCPUName(Name); + } + + void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override { + fillValidCPUList(Values); + } + bool setCPU(const std::string &Name) override { CPU = Name; ISARevision = getISARevision(CPU); @@ -128,12 +173,14 @@ public: } HasVector &= !SoftFloat; - // If we use the vector ABI, vector types are 64-bit aligned. - if (HasVector) { + // If we use the vector ABI, vector types are 64-bit aligned. The + // DataLayout string is always set to this alignment as it is not a + // requirement that it follows the alignment emitted by the front end. It + // is assumed generally that the Datalayout should reflect only the + // target triple and not any specific feature. + if (HasVector && !getTriple().isOSzOS()) MaxVectorAlign = 64; - resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" - "-v128:64-a:8:16-n32:64"); - } + return true; } @@ -160,7 +207,7 @@ public: const char *getLongDoubleMangling() const override { return "g"; } - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } int getEHDataRegisterNumber(unsigned RegNo) const override { return RegNo < 4 ? 6 + RegNo : -1; diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/TCE.h b/contrib/llvm-project/clang/lib/Basic/Targets/TCE.h index 251b4d4b56f7..dcf684fe6dbc 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/TCE.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/TCE.h @@ -15,8 +15,8 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { @@ -50,6 +50,10 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = { 0, // ptr32_sptr 0, // ptr32_uptr 0, // ptr64 + 0, // hlsl_groupshared + // Wasm address space values for this target are dummy values, + // as it is only enabled for Wasm targets. + 20, // wasm_funcref }; class LLVM_LIBRARY_VISIBILITY TCETargetInfo : public TargetInfo { @@ -91,15 +95,19 @@ public: bool hasFeature(StringRef Feature) const override { return Feature == "tce"; } - ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return std::nullopt; + } - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; } - ArrayRef<const char *> getGCCRegNames() const override { return None; } + ArrayRef<const char *> getGCCRegNames() const override { + return std::nullopt; + } bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override { @@ -107,7 +115,7 @@ public: } ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { - return None; + return std::nullopt; } }; diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/VE.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/VE.cpp index 22223654e8ad..67cae8faf605 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/VE.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/VE.cpp @@ -18,22 +18,28 @@ using namespace clang; using namespace clang::targets; +static constexpr Builtin::Info BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) \ + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#include "clang/Basic/BuiltinsVE.def" +}; + 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 + + 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"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); } ArrayRef<Builtin::Info> VETargetInfo::getTargetBuiltins() const { - return ArrayRef<Builtin::Info>(); + return llvm::ArrayRef(BuiltinInfo, + clang::VE::LastTSBuiltin - Builtin::FirstTSBuiltin); } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/VE.h b/contrib/llvm-project/clang/lib/Basic/Targets/VE.h index 71d6fc08d859..ea9a092cad80 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/VE.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/VE.h @@ -15,14 +15,13 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.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 &) @@ -70,7 +69,7 @@ public: } } - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } ArrayRef<const char *> getGCCRegNames() const override { static const char *const GCCRegNames[] = { @@ -84,7 +83,7 @@ public: "sx48", "sx49", "sx50", "sx51", "sx52", "sx53", "sx54", "sx55", "sx56", "sx57", "sx58", "sx59", "sx60", "sx61", "sx62", "sx63", }; - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { @@ -154,7 +153,7 @@ public: {{"s62"}, "sx62"}, {{"s63"}, "sx63"}, }; - return llvm::makeArrayRef(GCCRegAliases); + return llvm::ArrayRef(GCCRegAliases); } bool validateAsmConstraint(const char *&Name, diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.cpp index 7ef79849cb75..f1c925d90cb6 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.cpp @@ -20,13 +20,13 @@ using namespace clang; using namespace clang::targets; -const Builtin::Info WebAssemblyTargetInfo::BuiltinInfo[] = { +static constexpr Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsWebAssembly.def" }; @@ -46,6 +46,7 @@ bool WebAssemblyTargetInfo::setABI(const std::string &Name) { bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch<bool>(Feature) .Case("simd128", SIMDLevel >= SIMD128) + .Case("relaxed-simd", SIMDLevel >= RelaxedSIMD) .Case("nontrapping-fptoint", HasNontrappingFPToInt) .Case("sign-ext", HasSignExt) .Case("exception-handling", HasExceptionHandling) @@ -55,11 +56,13 @@ bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const { .Case("multivalue", HasMultivalue) .Case("tail-call", HasTailCall) .Case("reference-types", HasReferenceTypes) + .Case("extended-const", HasExtendedConst) + .Case("multimemory", HasMultiMemory) .Default(false); } bool WebAssemblyTargetInfo::isValidCPUName(StringRef Name) const { - return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); + return llvm::is_contained(ValidCPUNames, Name); } void WebAssemblyTargetInfo::fillValidCPUList( @@ -72,6 +75,8 @@ void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts, defineCPUMacros(Builder, "wasm", /*Tuning=*/false); if (SIMDLevel >= SIMD128) Builder.defineMacro("__wasm_simd128__"); + if (SIMDLevel >= RelaxedSIMD) + Builder.defineMacro("__wasm_relaxed_simd__"); if (HasNontrappingFPToInt) Builder.defineMacro("__wasm_nontrapping_fptoint__"); if (HasSignExt) @@ -90,15 +95,27 @@ void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__wasm_tail_call__"); if (HasReferenceTypes) Builder.defineMacro("__wasm_reference_types__"); + if (HasExtendedConst) + Builder.defineMacro("__wasm_extended_const__"); + if (HasMultiMemory) + Builder.defineMacro("__wasm_multimemory__"); + + 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"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); } void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap<bool> &Features, SIMDEnum Level, bool Enabled) { if (Enabled) { switch (Level) { + case RelaxedSIMD: + Features["relaxed-simd"] = true; + [[fallthrough]]; case SIMD128: Features["simd128"] = true; - LLVM_FALLTHROUGH; + [[fallthrough]]; case NoSIMD: break; } @@ -109,6 +126,9 @@ void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap<bool> &Features, case NoSIMD: case SIMD128: Features["simd128"] = false; + [[fallthrough]]; + case RelaxedSIMD: + Features["relaxed-simd"] = false; break; } } @@ -118,6 +138,8 @@ void WebAssemblyTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, bool Enabled) const { if (Name == "simd128") setSIMDLevel(Features, SIMD128, Enabled); + else if (Name == "relaxed-simd") + setSIMDLevel(Features, RelaxedSIMD, Enabled); else Features[Name] = Enabled; } @@ -132,7 +154,12 @@ bool WebAssemblyTargetInfo::initFeatureMap( Features["atomics"] = true; Features["mutable-globals"] = true; Features["tail-call"] = true; + Features["reference-types"] = true; + Features["multimemory"] = true; setSIMDLevel(Features, SIMD128, true); + } else if (CPU == "generic") { + Features["sign-ext"] = true; + Features["mutable-globals"] = true; } return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); @@ -149,6 +176,14 @@ bool WebAssemblyTargetInfo::handleTargetFeatures( SIMDLevel = std::min(SIMDLevel, SIMDEnum(SIMD128 - 1)); continue; } + if (Feature == "+relaxed-simd") { + SIMDLevel = std::max(SIMDLevel, RelaxedSIMD); + continue; + } + if (Feature == "-relaxed-simd") { + SIMDLevel = std::min(SIMDLevel, SIMDEnum(RelaxedSIMD - 1)); + continue; + } if (Feature == "+nontrapping-fptoint") { HasNontrappingFPToInt = true; continue; @@ -221,6 +256,22 @@ bool WebAssemblyTargetInfo::handleTargetFeatures( HasReferenceTypes = false; continue; } + if (Feature == "+extended-const") { + HasExtendedConst = true; + continue; + } + if (Feature == "-extended-const") { + HasExtendedConst = false; + continue; + } + if (Feature == "+multimemory") { + HasMultiMemory = true; + continue; + } + if (Feature == "-multimemory") { + HasMultiMemory = false; + continue; + } Diags.Report(diag::err_opt_not_valid_with_opt) << Feature << "-target-feature"; @@ -230,17 +281,20 @@ bool WebAssemblyTargetInfo::handleTargetFeatures( } ArrayRef<Builtin::Info> WebAssemblyTargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin - - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin - + Builtin::FirstTSBuiltin); } void WebAssemblyTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { - // If the Atomics feature isn't available, turn off POSIXThreads and - // ThreadModel, so that we don't predefine _REENTRANT or __STDCPP_THREADS__. - if (!HasAtomics) { + TargetInfo::adjust(Diags, Opts); + // Turn off POSIXThreads and ThreadModel so that we don't predefine _REENTRANT + // or __STDCPP_THREADS__ if we will eventually end up stripping atomics + // because they are unsupported. + if (!HasAtomics || !HasBulkMemory) { Opts.POSIXThreads = false; Opts.setThreadModel(LangOptions::ThreadModelKind::Single); + Opts.ThreadsafeStatics = false; } } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h b/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h index 4a5ba25c75e7..83b1711f9fdf 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h @@ -15,18 +15,42 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { +static const unsigned WebAssemblyAddrSpaceMap[] = { + 0, // Default + 0, // opencl_global + 0, // opencl_local + 0, // opencl_constant + 0, // opencl_private + 0, // opencl_generic + 0, // opencl_global_device + 0, // opencl_global_host + 0, // cuda_device + 0, // cuda_constant + 0, // cuda_shared + 0, // sycl_global + 0, // sycl_global_device + 0, // sycl_global_host + 0, // sycl_local + 0, // sycl_private + 0, // ptr32_sptr + 0, // ptr32_uptr + 0, // ptr64 + 0, // hlsl_groupshared + 20, // wasm_funcref +}; + class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo { - static const Builtin::Info BuiltinInfo[]; enum SIMDEnum { NoSIMD, SIMD128, + RelaxedSIMD, } SIMDLevel = NoSIMD; bool HasNontrappingFPToInt = false; @@ -38,17 +62,19 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo { bool HasMultivalue = false; bool HasTailCall = false; bool HasReferenceTypes = false; + bool HasExtendedConst = false; + bool HasMultiMemory = false; std::string ABI; public: explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &) : TargetInfo(T) { + AddrSpaceMap = &WebAssemblyAddrSpaceMap; NoAsmVariants = true; SuitableAlign = 128; LargeArrayMinWidth = 128; LargeArrayAlign = 128; - SimdDefaultAlign = 128; SigAtomicType = SignedLong; LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad(); @@ -94,10 +120,10 @@ private: return VoidPtrBuiltinVaList; } - ArrayRef<const char *> getGCCRegNames() const final { return None; } + ArrayRef<const char *> getGCCRegNames() const final { return std::nullopt; } ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final { - return None; + return std::nullopt; } bool validateAsmConstraint(const char *&Name, @@ -105,7 +131,7 @@ private: return false; } - const char *getClobbers() const final { return ""; } + std::string_view getClobbers() const final { return ""; } bool isCLZForZeroUndef() const final { return false; } @@ -136,7 +162,7 @@ private: } } - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } bool hasProtectedVisibility() const override { return false; } @@ -150,9 +176,11 @@ public: const TargetOptions &Opts) : WebAssemblyTargetInfo(T, Opts) { if (T.isOSEmscripten()) - resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32:64-S128-ni:1:10:20"); + resetDataLayout("e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-" + "S128-ni:1:10:20"); else - resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20"); + resetDataLayout( + "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"); } protected: @@ -172,9 +200,11 @@ public: PtrDiffType = SignedLong; IntPtrType = SignedLong; if (T.isOSEmscripten()) - resetDataLayout("e-m:e-p:64:64-i64:64-f128:64-n32:64-S128-ni:1:10:20"); + resetDataLayout("e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-" + "S128-ni:1:10:20"); else - resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128-ni:1:10:20"); + resetDataLayout( + "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"); } protected: diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp index 9db96c20250f..a68b662d9401 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp @@ -17,26 +17,27 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/X86TargetParser.h" +#include "llvm/TargetParser/X86TargetParser.h" +#include <optional> namespace clang { namespace targets { -const Builtin::Info BuiltinInfoX86[] = { +static constexpr Builtin::Info BuiltinInfoX86[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ - {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, #include "clang/Basic/BuiltinsX86.def" #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ - {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, #include "clang/Basic/BuiltinsX86_64.def" }; @@ -118,6 +119,14 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabled(Features, F, true); std::vector<std::string> UpdatedFeaturesVec; + std::vector<std::string> UpdatedAVX10FeaturesVec; + enum { FE_NOSET = -1, FE_FALSE, FE_TRUE }; + int HasEVEX512 = FE_NOSET; + bool HasAVX512F = Features.lookup("avx512f"); + bool HasAVX10 = Features.lookup("avx10.1-256"); + bool HasAVX10_512 = Features.lookup("avx10.1-512"); + std::string LastAVX10; + std::string LastAVX512; for (const auto &Feature : FeaturesVec) { // Expand general-regs-only to -x86, -mmx and -sse if (Feature == "+general-regs-only") { @@ -127,8 +136,51 @@ bool X86TargetInfo::initFeatureMap( continue; } + if (Feature.substr(1, 6) == "avx10.") { + if (Feature[0] == '+') { + HasAVX10 = true; + if (Feature.substr(Feature.size() - 3, 3) == "512") + HasAVX10_512 = true; + LastAVX10 = Feature; + } else if (HasAVX10 && Feature == "-avx10.1-256") { + HasAVX10 = false; + HasAVX10_512 = false; + } else if (HasAVX10_512 && Feature == "-avx10.1-512") { + HasAVX10_512 = false; + } + // Postpone AVX10 features handling after AVX512 settled. + UpdatedAVX10FeaturesVec.push_back(Feature); + continue; + } else if (!HasAVX512F && Feature.substr(0, 7) == "+avx512") { + HasAVX512F = true; + LastAVX512 = Feature; + } else if (HasAVX512F && Feature == "-avx512f") { + HasAVX512F = false; + } else if (HasEVEX512 != FE_TRUE && Feature == "+evex512") { + HasEVEX512 = FE_TRUE; + continue; + } else if (HasEVEX512 != FE_FALSE && Feature == "-evex512") { + HasEVEX512 = FE_FALSE; + continue; + } + UpdatedFeaturesVec.push_back(Feature); } + llvm::append_range(UpdatedFeaturesVec, UpdatedAVX10FeaturesVec); + // HasEVEX512 is a three-states flag. We need to turn it into [+-]evex512 + // according to other features. + if (HasAVX512F) { + UpdatedFeaturesVec.push_back(HasEVEX512 == FE_FALSE ? "-evex512" + : "+evex512"); + if (HasAVX10 && !HasAVX10_512 && HasEVEX512 != FE_FALSE) + Diags.Report(diag::warn_invalid_feature_combination) + << LastAVX512 + " " + LastAVX10 + "; will be promoted to avx10.1-512"; + } else if (HasAVX10) { + if (HasEVEX512 != FE_NOSET) + Diags.Report(diag::warn_invalid_feature_combination) + << LastAVX10 + (HasEVEX512 == FE_TRUE ? " +evex512" : " -evex512"); + UpdatedFeaturesVec.push_back(HasAVX10_512 ? "+evex512" : "-evex512"); + } if (!TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec)) return false; @@ -139,22 +191,28 @@ bool X86TargetInfo::initFeatureMap( // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled. auto I = Features.find("sse4.2"); if (I != Features.end() && I->getValue() && - llvm::find(UpdatedFeaturesVec, "-popcnt") == UpdatedFeaturesVec.end()) + !llvm::is_contained(UpdatedFeaturesVec, "-popcnt")) Features["popcnt"] = true; // Additionally, if SSE is enabled and mmx is not explicitly disabled, // then enable MMX. I = Features.find("sse"); if (I != Features.end() && I->getValue() && - llvm::find(UpdatedFeaturesVec, "-mmx") == UpdatedFeaturesVec.end()) + !llvm::is_contained(UpdatedFeaturesVec, "-mmx")) Features["mmx"] = true; // Enable xsave if avx is enabled and xsave is not explicitly disabled. I = Features.find("avx"); if (I != Features.end() && I->getValue() && - llvm::find(UpdatedFeaturesVec, "-xsave") == UpdatedFeaturesVec.end()) + !llvm::is_contained(UpdatedFeaturesVec, "-xsave")) Features["xsave"] = true; + // Enable CRC32 if SSE4.2 is enabled and CRC32 is not explicitly disabled. + I = Features.find("sse4.2"); + if (I != Features.end() && I->getValue() && + !llvm::is_contained(UpdatedFeaturesVec, "-crc32")) + Features["crc32"] = true; + return true; } @@ -221,6 +279,12 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasF16C = true; } else if (Feature == "+gfni") { HasGFNI = true; + } else if (Feature == "+evex512") { + HasEVEX512 = true; + } else if (Feature == "+avx10.1-256") { + HasAVX10_1 = true; + } else if (Feature == "+avx10.1-512") { + HasAVX10_1_512 = true; } else if (Feature == "+avx512cd") { HasAVX512CD = true; } else if (Feature == "+avx512vpopcntdq") { @@ -231,8 +295,13 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasAVX512BF16 = true; } else if (Feature == "+avx512er") { HasAVX512ER = true; + Diags.Report(diag::warn_knl_knm_isa_support_removed); + } else if (Feature == "+avx512fp16") { + HasAVX512FP16 = true; + HasLegalHalfType = true; } else if (Feature == "+avx512pf") { HasAVX512PF = true; + Diags.Report(diag::warn_knl_knm_isa_support_removed); } else if (Feature == "+avx512dq") { HasAVX512DQ = true; } else if (Feature == "+avx512bitalg") { @@ -251,8 +320,14 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasAVX512VP2INTERSECT = true; } else if (Feature == "+sha") { HasSHA = true; + } else if (Feature == "+sha512") { + HasSHA512 = true; } else if (Feature == "+shstk") { HasSHSTK = true; + } else if (Feature == "+sm3") { + HasSM3 = true; + } else if (Feature == "+sm4") { + HasSM4 = true; } else if (Feature == "+movbe") { HasMOVBE = true; } else if (Feature == "+sgx") { @@ -281,14 +356,19 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasCLWB = true; } else if (Feature == "+wbnoinvd") { HasWBNOINVD = true; + } else if (Feature == "+prefetchi") { + HasPREFETCHI = true; } else if (Feature == "+prefetchwt1") { HasPREFETCHWT1 = true; + Diags.Report(diag::warn_knl_knm_isa_support_removed); } else if (Feature == "+clzero") { HasCLZERO = true; } else if (Feature == "+cldemote") { HasCLDEMOTE = true; } else if (Feature == "+rdpid") { HasRDPID = true; + } else if (Feature == "+rdpru") { + HasRDPRU = true; } else if (Feature == "+kl") { HasKL = true; } else if (Feature == "+widekl") { @@ -315,18 +395,54 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasHRESET = true; } else if (Feature == "+amx-bf16") { HasAMXBF16 = true; + } else if (Feature == "+amx-fp16") { + HasAMXFP16 = true; } else if (Feature == "+amx-int8") { HasAMXINT8 = true; } else if (Feature == "+amx-tile") { HasAMXTILE = true; + } else if (Feature == "+amx-complex") { + HasAMXCOMPLEX = true; + } else if (Feature == "+cmpccxadd") { + HasCMPCCXADD = true; + } else if (Feature == "+raoint") { + HasRAOINT = true; + } else if (Feature == "+avxifma") { + HasAVXIFMA = true; + } else if (Feature == "+avxneconvert") { + HasAVXNECONVERT= true; } else if (Feature == "+avxvnni") { HasAVXVNNI = true; + } else if (Feature == "+avxvnniint16") { + HasAVXVNNIINT16 = true; + } else if (Feature == "+avxvnniint8") { + HasAVXVNNIINT8 = true; } else if (Feature == "+serialize") { HasSERIALIZE = true; } else if (Feature == "+tsxldtrk") { HasTSXLDTRK = true; } else if (Feature == "+uintr") { HasUINTR = true; + } else if (Feature == "+usermsr") { + HasUSERMSR = true; + } else if (Feature == "+crc32") { + HasCRC32 = true; + } else if (Feature == "+x87") { + HasX87 = true; + } else if (Feature == "+fullbf16") { + HasFullBFloat16 = true; + } else if (Feature == "+egpr") { + HasEGPR = true; + } else if (Feature == "+push2pop2") { + HasPush2Pop2 = true; + } else if (Feature == "+ppx") { + HasPPX = true; + } else if (Feature == "+ndd") { + HasNDD = true; + } else if (Feature == "+ccmp") { + HasCCMP = true; + } else if (Feature == "+cf") { + HasCF = true; } X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) @@ -342,6 +458,19 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, .Default(NoSSE); SSELevel = std::max(SSELevel, Level); + HasFloat16 = SSELevel >= SSE2; + + // X86 target has bfloat16 emulation support in the backend, where + // bfloat16 is treated as a 32-bit float, arithmetic operations are + // performed in 32-bit, and the result is converted back to bfloat16. + // Truncation and extension between bfloat16 and 32-bit float are supported + // by the compiler-rt library. However, native bfloat16 support is currently + // not available in the X86 target. Hence, HasFullBFloat16 will be false + // until native bfloat16 support is available. HasFullBFloat16 is used to + // determine whether to automatically use excess floating point precision + // for bfloat16 arithmetic operations in the front-end. + HasBFloat16 = SSELevel >= SSE2; + MMX3DNowEnum ThreeDNowLevel = llvm::StringSwitch<MMX3DNowEnum>(Feature) .Case("+3dnowa", AMD3DNowAthlon) .Case("+3dnow", AMD3DNow) @@ -366,8 +495,11 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, return false; } - SimdDefaultAlign = - hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128; + // FIXME: We should allow long double type on 32-bits to match with GCC. + // This requires backend to be able to lower f80 without x87 first. + if (!HasX87 && LongDoubleFormat == &llvm::APFloat::x87DoubleExtended()) + HasLongDouble = false; + return true; } @@ -422,7 +554,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_PentiumMMX: Builder.defineMacro("__pentium_mmx__"); Builder.defineMacro("__tune_pentium_mmx__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case CK_i586: case CK_Pentium: defineCPUMacros(Builder, "i586"); @@ -431,11 +563,11 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_Pentium3: case CK_PentiumM: Builder.defineMacro("__tune_pentium3__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case CK_Pentium2: case CK_C3_2: Builder.defineMacro("__tune_pentium2__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case CK_PentiumPro: case CK_i686: defineCPUMacros(Builder, "i686"); @@ -468,6 +600,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_Tremont: defineCPUMacros(Builder, "tremont"); break; + // Gracemont and later atom-cores use P-core cpu macros. + case CK_Gracemont: case CK_Nehalem: case CK_Westmere: case CK_SandyBridge: @@ -485,6 +619,18 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_Tigerlake: case CK_SapphireRapids: case CK_Alderlake: + case CK_Raptorlake: + case CK_Meteorlake: + case CK_Arrowlake: + case CK_ArrowlakeS: + case CK_Lunarlake: + case CK_Pantherlake: + case CK_Sierraforest: + case CK_Grandridge: + case CK_Graniterapids: + case CK_GraniterapidsD: + case CK_Emeraldrapids: + case CK_Clearwaterforest: // FIXME: Historically, we defined this legacy name, it would be nice to // remove it at some point. We've never exposed fine-grained names for // recent primary x86 CPUs, and we should keep it that way. @@ -503,7 +649,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_K6_2: Builder.defineMacro("__k6_2__"); Builder.defineMacro("__tune_k6_2__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case CK_K6_3: if (CPU != CK_K6_2) { // In case of fallthrough // FIXME: GCC may be enabling these in cases where some other k6 @@ -512,7 +658,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__k6_3__"); Builder.defineMacro("__tune_k6_3__"); } - LLVM_FALLTHROUGH; + [[fallthrough]]; case CK_K6: defineCPUMacros(Builder, "k6"); break; @@ -563,6 +709,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_ZNVER3: defineCPUMacros(Builder, "znver3"); break; + case CK_ZNVER4: + defineCPUMacros(Builder, "znver4"); + break; case CK_Geode: defineCPUMacros(Builder, "geode"); break; @@ -638,13 +787,13 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, switch (XOPLevel) { case XOP: Builder.defineMacro("__XOP__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case FMA4: Builder.defineMacro("__FMA4__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSE4A: Builder.defineMacro("__SSE4A__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case NoXOP: break; } @@ -658,6 +807,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasGFNI) Builder.defineMacro("__GFNI__"); + if (HasEVEX512) + Builder.defineMacro("__EVEX512__"); + if (HasAVX10_1) + Builder.defineMacro("__AVX10_1__"); + if (HasAVX10_1_512) + Builder.defineMacro("__AVX10_1_512__"); if (HasAVX512CD) Builder.defineMacro("__AVX512CD__"); if (HasAVX512VPOPCNTDQ) @@ -668,6 +823,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVX512BF16__"); if (HasAVX512ER) Builder.defineMacro("__AVX512ER__"); + if (HasAVX512FP16) + Builder.defineMacro("__AVX512FP16__"); if (HasAVX512PF) Builder.defineMacro("__AVX512PF__"); if (HasAVX512DQ) @@ -676,8 +833,10 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVX512BITALG__"); if (HasAVX512BW) Builder.defineMacro("__AVX512BW__"); - if (HasAVX512VL) + if (HasAVX512VL) { Builder.defineMacro("__AVX512VL__"); + Builder.defineMacro("__EVEX256__"); + } if (HasAVX512VBMI) Builder.defineMacro("__AVX512VBMI__"); if (HasAVX512VBMI2) @@ -688,6 +847,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVX512VP2INTERSECT__"); if (HasSHA) Builder.defineMacro("__SHA__"); + if (HasSHA512) + Builder.defineMacro("__SHA512__"); if (HasFXSR) Builder.defineMacro("__FXSR__"); @@ -711,6 +872,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__SHSTK__"); if (HasSGX) Builder.defineMacro("__SGX__"); + if (HasSM3) + Builder.defineMacro("__SM3__"); + if (HasSM4) + Builder.defineMacro("__SM4__"); + if (HasPREFETCHI) + Builder.defineMacro("__PREFETCHI__"); if (HasPREFETCHWT1) Builder.defineMacro("__PREFETCHWT1__"); if (HasCLZERO) @@ -721,6 +888,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__WIDEKL__"); if (HasRDPID) Builder.defineMacro("__RDPID__"); + if (HasRDPRU) + Builder.defineMacro("__RDPRU__"); if (HasCLDEMOTE) Builder.defineMacro("__CLDEMOTE__"); if (HasWAITPKG) @@ -740,51 +909,83 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasHRESET) Builder.defineMacro("__HRESET__"); if (HasAMXTILE) - Builder.defineMacro("__AMXTILE__"); + Builder.defineMacro("__AMX_TILE__"); if (HasAMXINT8) - Builder.defineMacro("__AMXINT8__"); + Builder.defineMacro("__AMX_INT8__"); if (HasAMXBF16) - Builder.defineMacro("__AMXBF16__"); + Builder.defineMacro("__AMX_BF16__"); + if (HasAMXFP16) + Builder.defineMacro("__AMX_FP16__"); + if (HasAMXCOMPLEX) + Builder.defineMacro("__AMX_COMPLEX__"); + if (HasCMPCCXADD) + Builder.defineMacro("__CMPCCXADD__"); + if (HasRAOINT) + Builder.defineMacro("__RAOINT__"); + if (HasAVXIFMA) + Builder.defineMacro("__AVXIFMA__"); + if (HasAVXNECONVERT) + Builder.defineMacro("__AVXNECONVERT__"); if (HasAVXVNNI) Builder.defineMacro("__AVXVNNI__"); + if (HasAVXVNNIINT16) + Builder.defineMacro("__AVXVNNIINT16__"); + if (HasAVXVNNIINT8) + Builder.defineMacro("__AVXVNNIINT8__"); if (HasSERIALIZE) Builder.defineMacro("__SERIALIZE__"); if (HasTSXLDTRK) Builder.defineMacro("__TSXLDTRK__"); if (HasUINTR) Builder.defineMacro("__UINTR__"); + if (HasUSERMSR) + Builder.defineMacro("__USERMSR__"); + if (HasCRC32) + Builder.defineMacro("__CRC32__"); + if (HasEGPR) + Builder.defineMacro("__EGPR__"); + if (HasPush2Pop2) + Builder.defineMacro("__PUSH2POP2__"); + if (HasPPX) + Builder.defineMacro("__PPX__"); + if (HasNDD) + Builder.defineMacro("__NDD__"); + if (HasCCMP) + Builder.defineMacro("__CCMP__"); + if (HasCF) + Builder.defineMacro("__CF__"); // Each case falls through to the previous one here. switch (SSELevel) { case AVX512F: Builder.defineMacro("__AVX512F__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case AVX2: Builder.defineMacro("__AVX2__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case AVX: Builder.defineMacro("__AVX__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSE42: Builder.defineMacro("__SSE4_2__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSE41: Builder.defineMacro("__SSE4_1__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSSE3: Builder.defineMacro("__SSSE3__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSE3: Builder.defineMacro("__SSE3__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSE2: Builder.defineMacro("__SSE2__"); Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied. - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSE1: Builder.defineMacro("__SSE__"); Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied. - LLVM_FALLTHROUGH; + [[fallthrough]]; case NoSSE: break; } @@ -814,13 +1015,13 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, switch (MMX3DNowLevel) { case AMD3DNowAthlon: Builder.defineMacro("__3dNOW_A__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case AMD3DNow: Builder.defineMacro("__3dNOW__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case MMX: Builder.defineMacro("__MMX__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case NoMMX3DNow: break; } @@ -846,9 +1047,13 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("adx", true) .Case("aes", true) .Case("amx-bf16", true) + .Case("amx-complex", true) + .Case("amx-fp16", true) .Case("amx-int8", true) .Case("amx-tile", true) .Case("avx", true) + .Case("avx10.1-256", true) + .Case("avx10.1-512", true) .Case("avx2", true) .Case("avx512f", true) .Case("avx512cd", true) @@ -856,6 +1061,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("avx512vnni", true) .Case("avx512bf16", true) .Case("avx512er", true) + .Case("avx512fp16", true) .Case("avx512pf", true) .Case("avx512dq", true) .Case("avx512bitalg", true) @@ -865,15 +1071,22 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("avx512vbmi2", true) .Case("avx512ifma", true) .Case("avx512vp2intersect", true) + .Case("avxifma", true) + .Case("avxneconvert", true) .Case("avxvnni", true) + .Case("avxvnniint16", true) + .Case("avxvnniint8", true) .Case("bmi", true) .Case("bmi2", true) .Case("cldemote", true) .Case("clflushopt", true) .Case("clwb", true) .Case("clzero", true) + .Case("cmpccxadd", true) + .Case("crc32", true) .Case("cx16", true) .Case("enqcmd", true) + .Case("evex512", true) .Case("f16c", true) .Case("fma", true) .Case("fma4", true) @@ -896,10 +1109,13 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("pconfig", true) .Case("pku", true) .Case("popcnt", true) + .Case("prefetchi", true) .Case("prefetchwt1", true) .Case("prfchw", true) .Case("ptwrite", true) + .Case("raoint", true) .Case("rdpid", true) + .Case("rdpru", true) .Case("rdrnd", true) .Case("rdseed", true) .Case("rtm", true) @@ -907,7 +1123,10 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("serialize", true) .Case("sgx", true) .Case("sha", true) + .Case("sha512", true) .Case("shstk", true) + .Case("sm3", true) + .Case("sm4", true) .Case("sse", true) .Case("sse2", true) .Case("sse3", true) @@ -919,6 +1138,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("tbm", true) .Case("tsxldtrk", true) .Case("uintr", true) + .Case("usermsr", true) .Case("vaes", true) .Case("vpclmulqdq", true) .Case("wbnoinvd", true) @@ -929,6 +1149,12 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("xsavec", true) .Case("xsaves", true) .Case("xsaveopt", true) + .Case("egpr", true) + .Case("push2pop2", true) + .Case("ppx", true) + .Case("ndd", true) + .Case("ccmp", true) + .Case("cf", true) .Default(false); } @@ -937,10 +1163,13 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("adx", HasADX) .Case("aes", HasAES) .Case("amx-bf16", HasAMXBF16) + .Case("amx-complex", HasAMXCOMPLEX) + .Case("amx-fp16", HasAMXFP16) .Case("amx-int8", HasAMXINT8) .Case("amx-tile", HasAMXTILE) - .Case("avxvnni", HasAVXVNNI) .Case("avx", SSELevel >= AVX) + .Case("avx10.1-256", HasAVX10_1) + .Case("avx10.1-512", HasAVX10_1_512) .Case("avx2", SSELevel >= AVX2) .Case("avx512f", SSELevel >= AVX512F) .Case("avx512cd", HasAVX512CD) @@ -948,6 +1177,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("avx512vnni", HasAVX512VNNI) .Case("avx512bf16", HasAVX512BF16) .Case("avx512er", HasAVX512ER) + .Case("avx512fp16", HasAVX512FP16) .Case("avx512pf", HasAVX512PF) .Case("avx512dq", HasAVX512DQ) .Case("avx512bitalg", HasAVX512BITALG) @@ -957,15 +1187,23 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("avx512vbmi2", HasAVX512VBMI2) .Case("avx512ifma", HasAVX512IFMA) .Case("avx512vp2intersect", HasAVX512VP2INTERSECT) + .Case("avxifma", HasAVXIFMA) + .Case("avxneconvert", HasAVXNECONVERT) + .Case("avxvnni", HasAVXVNNI) + .Case("avxvnniint16", HasAVXVNNIINT16) + .Case("avxvnniint8", HasAVXVNNIINT8) .Case("bmi", HasBMI) .Case("bmi2", HasBMI2) .Case("cldemote", HasCLDEMOTE) .Case("clflushopt", HasCLFLUSHOPT) .Case("clwb", HasCLWB) .Case("clzero", HasCLZERO) + .Case("cmpccxadd", HasCMPCCXADD) + .Case("crc32", HasCRC32) .Case("cx8", HasCX8) .Case("cx16", HasCX16) .Case("enqcmd", HasENQCMD) + .Case("evex512", HasEVEX512) .Case("f16c", HasF16C) .Case("fma", HasFMA) .Case("fma4", XOPLevel >= FMA4) @@ -989,10 +1227,13 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("pconfig", HasPCONFIG) .Case("pku", HasPKU) .Case("popcnt", HasPOPCNT) + .Case("prefetchi", HasPREFETCHI) .Case("prefetchwt1", HasPREFETCHWT1) .Case("prfchw", HasPRFCHW) .Case("ptwrite", HasPTWRITE) + .Case("raoint", HasRAOINT) .Case("rdpid", HasRDPID) + .Case("rdpru", HasRDPRU) .Case("rdrnd", HasRDRND) .Case("rdseed", HasRDSEED) .Case("retpoline-external-thunk", HasRetpolineExternalThunk) @@ -1001,7 +1242,10 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("serialize", HasSERIALIZE) .Case("sgx", HasSGX) .Case("sha", HasSHA) + .Case("sha512", HasSHA512) .Case("shstk", HasSHSTK) + .Case("sm3", HasSM3) + .Case("sm4", HasSM4) .Case("sse", SSELevel >= SSE1) .Case("sse2", SSELevel >= SSE2) .Case("sse3", SSELevel >= SSE3) @@ -1012,6 +1256,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("tbm", HasTBM) .Case("tsxldtrk", HasTSXLDTRK) .Case("uintr", HasUINTR) + .Case("usermsr", HasUSERMSR) .Case("vaes", HasVAES) .Case("vpclmulqdq", HasVPCLMULQDQ) .Case("wbnoinvd", HasWBNOINVD) @@ -1019,11 +1264,19 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("x86", true) .Case("x86_32", getTriple().getArch() == llvm::Triple::x86) .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64) + .Case("x87", HasX87) .Case("xop", XOPLevel >= XOP) .Case("xsave", HasXSAVE) .Case("xsavec", HasXSAVEC) .Case("xsaves", HasXSAVES) .Case("xsaveopt", HasXSAVEOPT) + .Case("fullbf16", HasFullBFloat16) + .Case("egpr", HasEGPR) + .Case("push2pop2", HasPush2Pop2) + .Case("ppx", HasPPX) + .Case("ndd", HasNDD) + .Case("ccmp", HasCCMP) + .Case("cf", HasCF) .Default(false); } @@ -1034,35 +1287,23 @@ 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(ENUM, STR) .Case(STR, true) -#include "llvm/Support/X86TargetParser.def" +#define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) .Case(STR, true) +#define X86_MICROARCH_LEVEL(ENUM, STR, PRIORITY) .Case(STR, true) +#include "llvm/TargetParser/X86TargetParser.def" .Default(false); } static llvm::X86::ProcessorFeatures getFeature(StringRef Name) { return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name) -#define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, llvm::X86::FEATURE_##ENUM) -#include "llvm/Support/X86TargetParser.def" +#define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \ + .Case(STR, llvm::X86::FEATURE_##ENUM) + +#include "llvm/TargetParser/X86TargetParser.def" ; // Note, this function should only be used after ensuring the value is // correct, so it asserts if the value is out of range. } -static unsigned getFeaturePriority(llvm::X86::ProcessorFeatures Feat) { - enum class FeatPriority { -#define FEATURE(FEAT) FEAT, -#include "clang/Basic/X86Target.def" - }; - switch (Feat) { -#define FEATURE(FEAT) \ - case llvm::X86::FEAT: \ - return static_cast<unsigned>(FeatPriority::FEAT); -#include "clang/Basic/X86Target.def" - default: - llvm_unreachable("No Feature Priority for non-CPUSupports Features"); - } -} - unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const { // Valid CPUs have a 'key feature' that compares just better than its key // feature. @@ -1079,35 +1320,19 @@ unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const { } bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const { - return llvm::StringSwitch<bool>(Name) -#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, true) -#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, true) -#include "clang/Basic/X86Target.def" - .Default(false); -} - -static StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) { - return llvm::StringSwitch<StringRef>(Name) -#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, NAME) -#include "clang/Basic/X86Target.def" - .Default(Name); + return llvm::X86::validateCPUSpecificCPUDispatch(Name); } char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const { - return llvm::StringSwitch<char>(CPUSpecificCPUDispatchNameDealias(Name)) -#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, MANGLING) -#include "clang/Basic/X86Target.def" - .Default(0); + return llvm::X86::getCPUDispatchMangling(Name); } void X86TargetInfo::getCPUSpecificCPUDispatchFeatures( StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const { - StringRef WholeList = - llvm::StringSwitch<StringRef>(CPUSpecificCPUDispatchNameDealias(Name)) -#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, FEATURES) -#include "clang/Basic/X86Target.def" - .Default(""); - WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false); + SmallVector<StringRef, 32> TargetCPUFeatures; + llvm::X86::getFeaturesForCPU(Name, TargetCPUFeatures, true); + for (auto &F : TargetCPUFeatures) + Features.push_back(F); } // We can't use a generic validation scheme for the cpus accepted here @@ -1119,12 +1344,13 @@ bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const { #define X86_VENDOR(ENUM, STRING) .Case(STRING, true) #define X86_CPU_TYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true) #define X86_CPU_TYPE(ENUM, STR) .Case(STR, true) +#define X86_CPU_SUBTYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true) #define X86_CPU_SUBTYPE(ENUM, STR) .Case(STR, true) -#include "llvm/Support/X86TargetParser.def" +#include "llvm/TargetParser/X86TargetParser.def" .Default(false); } -static unsigned matchAsmCCConstraint(const char *&Name) { +static unsigned matchAsmCCConstraint(const char *Name) { auto RV = llvm::StringSwitch<unsigned>(Name) .Case("@cca", 4) .Case("@ccae", 5) @@ -1192,6 +1418,14 @@ bool X86TargetInfo::validateAsmConstraint( case 'O': Info.setRequiresImmediate(0, 127); return true; + case 'W': + switch (*++Name) { + default: + return false; + case 's': + Info.setAllowsRegister(); + return true; + } // Register constraints. case 'Y': // 'Y' is the first character for several 2-character constraints. // Shift the pointer to the second character of the constraint. @@ -1264,7 +1498,7 @@ bool X86TargetInfo::validateAsmConstraint( // | 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 | +// | Broadwell | 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" | @@ -1272,7 +1506,7 @@ bool X86TargetInfo::validateAsmConstraint( // | 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 { +std::optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { using namespace llvm::X86; switch (CPU) { // i386 @@ -1315,6 +1549,7 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { case CK_Goldmont: case CK_GoldmontPlus: case CK_Tremont: + case CK_Gracemont: case CK_Westmere: case CK_SandyBridge: @@ -1333,6 +1568,18 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { case CK_Rocketlake: case CK_IcelakeServer: case CK_Alderlake: + case CK_Raptorlake: + case CK_Meteorlake: + case CK_Arrowlake: + case CK_ArrowlakeS: + case CK_Lunarlake: + case CK_Pantherlake: + case CK_Sierraforest: + case CK_Grandridge: + case CK_Graniterapids: + case CK_GraniterapidsD: + case CK_Emeraldrapids: + case CK_Clearwaterforest: case CK_KNL: case CK_KNM: // K7 @@ -1354,6 +1601,7 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { case CK_ZNVER1: case CK_ZNVER2: case CK_ZNVER3: + case CK_ZNVER4: // Deprecated case CK_x86_64: case CK_x86_64_v2: @@ -1367,7 +1615,7 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { // The following currently have unknown cache line sizes (but they are probably all 64): // Core case CK_None: - return None; + return std::nullopt; } llvm_unreachable("Unknown CPU kind"); } @@ -1376,8 +1624,7 @@ bool X86TargetInfo::validateOutputSize(const llvm::StringMap<bool> &FeatureMap, StringRef Constraint, unsigned Size) const { // Strip off constraint modifiers. - while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') - Constraint = Constraint.substr(1); + Constraint = Constraint.ltrim("=+&"); return validateOperandSize(FeatureMap, Constraint, Size); } @@ -1413,8 +1660,9 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap, return Size <= 64; case 'z': // XMM0/YMM/ZMM0 - if (hasFeatureEnabled(FeatureMap, "avx512f")) - // ZMM0 can be used if target supports AVX512F. + if (hasFeatureEnabled(FeatureMap, "avx512f") && + hasFeatureEnabled(FeatureMap, "evex512")) + // ZMM0 can be used if target supports AVX512F and EVEX512 is set. return Size <= 512U; else if (hasFeatureEnabled(FeatureMap, "avx")) // YMM0 can be used if target supports AVX. @@ -1433,8 +1681,10 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap, break; case 'v': case 'x': - if (hasFeatureEnabled(FeatureMap, "avx512f")) - // 512-bit zmm registers can be used if target supports AVX512F. + if (hasFeatureEnabled(FeatureMap, "avx512f") && + hasFeatureEnabled(FeatureMap, "evex512")) + // 512-bit zmm registers can be used if target supports AVX512F and + // EVEX512 is set. return Size <= 512U; else if (hasFeatureEnabled(FeatureMap, "avx")) // 256-bit ymm registers can be used if target supports AVX. @@ -1467,12 +1717,15 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const { return std::string("{si}"); case 'D': return std::string("{di}"); - case 'p': // address - return std::string("im"); + case 'p': // Keep 'p' constraint (address). + return std::string("p"); case 't': // top of floating point stack. return std::string("{st}"); case 'u': // second from top of floating point stack. return std::string("{st(1)}"); // second from top of floating point stack. + case 'W': + assert(Constraint[1] == 's'); + return '^' + std::string(Constraint++, 2); case 'Y': switch (Constraint[1]) { default: @@ -1491,7 +1744,7 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const { // to the next constraint. return std::string("^") + std::string(Constraint++, 2); } - LLVM_FALLTHROUGH; + [[fallthrough]]; default: return std::string(1, *Constraint); } @@ -1507,19 +1760,19 @@ void X86TargetInfo::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) con } ArrayRef<const char *> X86TargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const { - return llvm::makeArrayRef(AddlRegNames); + return llvm::ArrayRef(AddlRegNames); } ArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin - - Builtin::FirstTSBuiltin + 1); + return llvm::ArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin - + Builtin::FirstTSBuiltin + 1); } ArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfoX86, - X86::LastTSBuiltin - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfoX86, + X86::LastTSBuiltin - Builtin::FirstTSBuiltin); } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/X86.h b/contrib/llvm-project/clang/lib/Basic/Targets/X86.h index fcaaf50624e9..0ab1c10833db 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/X86.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/X86.h @@ -14,11 +14,13 @@ #define LLVM_CLANG_LIB_BASIC_TARGETS_X86_H #include "OSTargets.h" +#include "clang/Basic/BitmaskEnum.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/X86TargetParser.h" +#include "llvm/TargetParser/Triple.h" +#include "llvm/TargetParser/X86TargetParser.h" +#include <optional> namespace clang { namespace targets { @@ -42,7 +44,11 @@ static const unsigned X86AddrSpaceMap[] = { 0, // sycl_private 270, // ptr32_sptr 271, // ptr32_uptr - 272 // ptr64 + 272, // ptr64 + 0, // hlsl_groupshared + // Wasm address space values for this target are dummy values, + // as it is only enabled for Wasm targets. + 20, // wasm_funcref }; // X86 target abstract base class; x86-32 and x86-64 are very close, so @@ -89,9 +95,13 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasLWP = false; bool HasFMA = false; bool HasF16C = false; + bool HasAVX10_1 = false; + bool HasAVX10_1_512 = false; + bool HasEVEX512 = false; bool HasAVX512CD = false; bool HasAVX512VPOPCNTDQ = false; bool HasAVX512VNNI = false; + bool HasAVX512FP16 = false; bool HasAVX512BF16 = false; bool HasAVX512ER = false; bool HasAVX512PF = false; @@ -101,11 +111,15 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasAVX512VL = false; bool HasAVX512VBMI = false; bool HasAVX512VBMI2 = false; + bool HasAVXIFMA = false; bool HasAVX512IFMA = false; bool HasAVX512VP2INTERSECT = false; bool HasSHA = false; + bool HasSHA512 = false; bool HasSHSTK = false; + bool HasSM3 = false; bool HasSGX = false; + bool HasSM4 = false; bool HasCX8 = false; bool HasCX16 = false; bool HasFXSR = false; @@ -121,8 +135,10 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasCLFLUSHOPT = false; bool HasCLWB = false; bool HasMOVBE = false; + bool HasPREFETCHI = false; bool HasPREFETCHWT1 = false; bool HasRDPID = false; + bool HasRDPRU = false; bool HasRetpolineExternalThunk = false; bool HasLAHFSAHF = false; bool HasWBNOINVD = false; @@ -132,6 +148,12 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasPTWRITE = false; bool HasINVPCID = false; bool HasENQCMD = false; + bool HasAVXVNNIINT16 = false; + bool HasAMXFP16 = false; + bool HasCMPCCXADD = false; + bool HasRAOINT = false; + bool HasAVXVNNIINT8 = false; + bool HasAVXNECONVERT = false; bool HasKL = false; // For key locker bool HasWIDEKL = false; // For wide key locker bool HasHRESET = false; @@ -139,9 +161,19 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasAMXTILE = false; bool HasAMXINT8 = false; bool HasAMXBF16 = false; + bool HasAMXCOMPLEX = false; bool HasSERIALIZE = false; bool HasTSXLDTRK = false; + bool HasUSERMSR = false; bool HasUINTR = false; + bool HasCRC32 = false; + bool HasX87 = false; + bool HasEGPR = false; + bool HasPush2Pop2 = false; + bool HasPPX = false; + bool HasNDD = false; + bool HasCCMP = false; + bool HasCF = false; protected: llvm::X86::CPUKind CPU = llvm::X86::CK_None; @@ -151,6 +183,8 @@ protected: public: X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { + BFloat16Width = BFloat16Align = 16; + BFloat16Format = &llvm::APFloat::BFloat(); LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); AddrSpaceMap = &X86AddrSpaceMap; HasStrictFP = true; @@ -165,15 +199,19 @@ public: return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e"; } - unsigned getFloatEvalMethod() const override { + LangOptions::FPEvalMethodKind getFPEvalMethod() const override { // X87 evaluates with 80 bits "long double" precision. - return SSELevel == NoSSE ? 2 : 0; + return SSELevel == NoSSE ? LangOptions::FPEvalMethodKind::FEM_Extended + : LangOptions::FPEvalMethodKind::FEM_Source; } + // EvalMethod `source` is not supported for targets with `NoSSE` feature. + bool supportSourceEvalMethod() const override { return SSELevel > NoSSE; } + ArrayRef<const char *> getGCCRegNames() const override; ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { - return None; + return std::nullopt; } ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; @@ -182,9 +220,9 @@ public: return RegName.equals("esp") || RegName.equals("rsp"); } - bool validateCpuSupports(StringRef Name) const override; + bool validateCpuSupports(StringRef FeatureStr) const override; - bool validateCpuIs(StringRef Name) const override; + bool validateCpuIs(StringRef FeatureStr) const override; bool validateCPUSpecificCPUDispatch(StringRef Name) const override; @@ -194,7 +232,7 @@ public: StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const override; - Optional<unsigned> getCPUCacheLineSize() const override; + std::optional<unsigned> getCPUCacheLineSize() const override; bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override; @@ -218,21 +256,25 @@ public: bool validateInputSize(const llvm::StringMap<bool> &FeatureMap, StringRef Constraint, unsigned Size) const override; - virtual bool + bool checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override { - return true; + if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro) + return true; + return TargetInfo::checkCFProtectionReturnSupported(Diags); }; - virtual bool + bool checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override { - return true; + if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro) + return true; + return TargetInfo::checkCFProtectionBranchSupported(Diags); }; virtual bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap, StringRef Constraint, unsigned Size) const; std::string convertConstraint(const char *&Constraint) const override; - const char *getClobbers() const override { + std::string_view getClobbers() const override { return "~{dirflag},~{fpsr},~{flags}"; } @@ -374,17 +416,19 @@ public: void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); } - uint64_t getPointerWidthV(unsigned AddrSpace) const override { - if (AddrSpace == ptr32_sptr || AddrSpace == ptr32_uptr) + uint64_t getPointerWidthV(LangAS AS) const override { + unsigned TargetAddrSpace = getTargetAddressSpace(AS); + if (TargetAddrSpace == ptr32_sptr || TargetAddrSpace == ptr32_uptr) return 32; - if (AddrSpace == ptr64) + if (TargetAddrSpace == ptr64) return 64; return PointerWidth; } - uint64_t getPointerAlignV(unsigned AddrSpace) const override { + uint64_t getPointerAlignV(LangAS AddrSpace) const override { return getPointerWidthV(AddrSpace); } + }; // X86-32 generic target @@ -396,22 +440,21 @@ public: LongDoubleWidth = 96; LongDoubleAlign = 32; SuitableAlign = 128; - resetDataLayout( - Triple.isOSBinFormatMachO() - ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-" - "f80:32-n8:16:32-S128" - : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-" - "f80:32-n8:16:32-S128", - Triple.isOSBinFormatMachO() ? "_" : ""); + resetDataLayout(Triple.isOSBinFormatMachO() + ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:" + "128-f64:32:64-f80:32-n8:16:32-S128" + : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:" + "128-f64:32:64-f80:32-n8:16:32-S128", + Triple.isOSBinFormatMachO() ? "_" : ""); SizeType = UnsignedInt; PtrDiffType = SignedInt; IntPtrType = SignedInt; RegParmMax = 3; // Use fpret for all types. - RealTypeUsesObjCFPRet = - ((1 << TargetInfo::Float) | (1 << TargetInfo::Double) | - (1 << TargetInfo::LongDouble)); + RealTypeUsesObjCFPRetMask = + (unsigned)(FloatModeKind::Float | FloatModeKind::Double | + FloatModeKind::LongDouble); // x86-32 has atomics up to 8 bytes MaxAtomicPromoteWidth = 64; @@ -459,7 +502,10 @@ public: ArrayRef<Builtin::Info> getTargetBuiltins() const override; - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } + size_t getMaxBitIntWidth() const override { + return llvm::IntegerType::MAX_INT_BITS; + } }; class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo @@ -468,14 +514,13 @@ public: NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {} - unsigned getFloatEvalMethod() const override { - unsigned Major, Minor, Micro; - getTriple().getOSVersion(Major, Minor, Micro); + LangOptions::FPEvalMethodKind getFPEvalMethod() const override { + VersionTuple OsVersion = getTriple().getOSVersion(); // New NetBSD uses the default rounding mode. - if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 26) || Major == 0) - return X86_32TargetInfo::getFloatEvalMethod(); + if (OsVersion >= VersionTuple(6, 99, 26) || OsVersion.getMajor() == 0) + return X86_32TargetInfo::getFPEvalMethod(); // NetBSD before 6.99.26 defaults to "double" rounding. - return 1; + return LangOptions::FPEvalMethodKind::FEM_Double; } }; @@ -505,8 +550,9 @@ public: UseSignedCharForObjCBool = false; SizeType = UnsignedLong; IntPtrType = SignedLong; - resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-" - "f80:128-n8:16:32-S128", "_"); + resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-" + "f64:32:64-f80:128-n8:16:32-S128", + "_"); HasAlignMac68kSupport = true; } @@ -531,11 +577,12 @@ public: DoubleAlign = LongLongAlign = 64; bool IsWinCOFF = getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); - resetDataLayout(IsWinCOFF ? "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:" - "64-i64:64-f80:32-n8:16:32-a:0:32-S32" - : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:" - "64-i64:64-f80:32-n8:16:32-a:0:32-S32", - IsWinCOFF ? "_" : ""); + bool IsMSVC = getTriple().isWindowsMSVCEnvironment(); + std::string Layout = IsWinCOFF ? "e-m:x" : "e-m:e"; + Layout += "-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"; + Layout += IsMSVC ? "f80:128" : "f80:32"; + Layout += "-n8:16:32-a:0:32-S32"; + resetDataLayout(Layout, IsWinCOFF ? "_" : ""); } }; @@ -583,8 +630,8 @@ public: : X86_32TargetInfo(Triple, Opts) { this->WCharType = TargetInfo::UnsignedShort; DoubleAlign = LongLongAlign = 64; - resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:" - "32-n8:16:32-a:0:32-S32", + resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-" + "i128:128-f80:32-n8:16:32-a:0:32-S32", "_"); } @@ -622,8 +669,8 @@ public: : X86_32TargetInfo(Triple, Opts) { LongDoubleWidth = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble(); - resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-f64:" - "32-f128:32-n8:16:32-a:0:32-S32"); + resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-" + "f64:32-f128:32-n8:16:32-a:0:32-S32"); WIntType = UnsignedInt; } @@ -683,14 +730,14 @@ public: // Pointers are 32-bit in x32. resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-" - "i64:64-f80:128-n8:16:32:64-S128" - : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:" - "64-i64:64-f80:128-n8:16:32:64-S128" - : "e-m:e-p270:32:32-p271:32:32-p272:64:" - "64-i64:64-f80:128-n8:16:32:64-S128"); + "i64:64-i128:128-f80:128-n8:16:32:64-S128" + : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:" + "64-i128:128-f80:128-n8:16:32:64-S128" + : "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:" + "64-i128:128-f80:128-n8:16:32:64-S128"); // Use fpret only for long double. - RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble); + RealTypeUsesObjCFPRetMask = (unsigned)FloatModeKind::LongDouble; // Use fp2ret for _Complex long double. ComplexLongDoubleUsesFP2Ret = true; @@ -766,7 +813,10 @@ public: ArrayRef<Builtin::Info> getTargetBuiltins() const override; - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } + size_t getMaxBitIntWidth() const override { + return llvm::IntegerType::MAX_INT_BITS; + } }; // x86-64 Windows target @@ -881,8 +931,9 @@ public: llvm::Triple T = llvm::Triple(Triple); if (T.isiOS()) UseSignedCharForObjCBool = false; - resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:" - "16:32:64-S128", "_"); + resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-" + "f80:128-n8:16:32:64-S128", + "_"); } bool handleTargetFeatures(std::vector<std::string> &Features, @@ -928,6 +979,28 @@ public: LongDoubleFormat = &llvm::APFloat::IEEEquad(); } }; + +// x86_32 OHOS target +class LLVM_LIBRARY_VISIBILITY OHOSX86_32TargetInfo + : public OHOSTargetInfo<X86_32TargetInfo> { +public: + OHOSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OHOSTargetInfo<X86_32TargetInfo>(Triple, Opts) { + SuitableAlign = 32; + LongDoubleWidth = 64; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } +}; + +// x86_64 OHOS target +class LLVM_LIBRARY_VISIBILITY OHOSX86_64TargetInfo + : public OHOSTargetInfo<X86_64TargetInfo> { +public: + OHOSX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OHOSTargetInfo<X86_64TargetInfo>(Triple, Opts) { + LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } +}; } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/XCore.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/XCore.cpp index ba64f15f3394..fd377bbfb90e 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/XCore.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/XCore.cpp @@ -18,11 +18,11 @@ using namespace clang; using namespace clang::targets; -const Builtin::Info XCoreTargetInfo::BuiltinInfo[] = { +static constexpr Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, #include "clang/Basic/BuiltinsXCore.def" }; @@ -33,6 +33,6 @@ void XCoreTargetInfo::getTargetDefines(const LangOptions &Opts, } ArrayRef<Builtin::Info> XCoreTargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfo, clang::XCore::LastTSBuiltin - - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfo, + clang::XCore::LastTSBuiltin - Builtin::FirstTSBuiltin); } diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/XCore.h b/contrib/llvm-project/clang/lib/Basic/Targets/XCore.h index c33766751aa1..a58d3e8acf47 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/XCore.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/XCore.h @@ -15,14 +15,13 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" namespace clang { namespace targets { class LLVM_LIBRARY_VISIBILITY XCoreTargetInfo : public TargetInfo { - static const Builtin::Info BuiltinInfo[]; public: XCoreTargetInfo(const llvm::Triple &Triple, const TargetOptions &) @@ -50,18 +49,18 @@ public: return TargetInfo::VoidPtrBuiltinVaList; } - const char *getClobbers() const override { return ""; } + std::string_view getClobbers() const override { return ""; } ArrayRef<const char *> getGCCRegNames() const override { static const char *const GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cp", "dp", "sp", "lr" }; - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { - return None; + return std::nullopt; } bool validateAsmConstraint(const char *&Name, @@ -76,7 +75,7 @@ public: bool allowsLargerPreferedTypeAlignment() const override { return false; } - bool hasExtIntType() const override { return true; } + bool hasBitIntType() const override { return true; } }; } // namespace targets } // namespace clang diff --git a/contrib/llvm-project/clang/lib/Basic/TokenKinds.cpp b/contrib/llvm-project/clang/lib/Basic/TokenKinds.cpp index d55e176c72c4..c300175ce90b 100644 --- a/contrib/llvm-project/clang/lib/Basic/TokenKinds.cpp +++ b/contrib/llvm-project/clang/lib/Basic/TokenKinds.cpp @@ -46,6 +46,15 @@ const char *tok::getKeywordSpelling(TokenKind Kind) { return nullptr; } +const char *tok::getPPKeywordSpelling(tok::PPKeywordKind Kind) { + switch (Kind) { +#define PPKEYWORD(x) case tok::pp_##x: return #x; +#include "clang/Basic/TokenKinds.def" + default: break; + } + return nullptr; +} + bool tok::isAnnotation(TokenKind Kind) { switch (Kind) { #define ANNOTATION(X) case annot_ ## X: return true; diff --git a/contrib/llvm-project/clang/lib/Basic/TypeTraits.cpp b/contrib/llvm-project/clang/lib/Basic/TypeTraits.cpp index 3b723afff70b..4dbf678dc395 100644 --- a/contrib/llvm-project/clang/lib/Basic/TypeTraits.cpp +++ b/contrib/llvm-project/clang/lib/Basic/TypeTraits.cpp @@ -55,6 +55,15 @@ static constexpr const char *UnaryExprOrTypeTraitSpellings[] = { #include "clang/Basic/TokenKinds.def" }; +static constexpr const unsigned TypeTraitArities[] = { +#define TYPE_TRAIT_1(Spelling, Name, Key) 1, +#include "clang/Basic/TokenKinds.def" +#define TYPE_TRAIT_2(Spelling, Name, Key) 2, +#include "clang/Basic/TokenKinds.def" +#define TYPE_TRAIT_N(Spelling, Name, Key) 0, +#include "clang/Basic/TokenKinds.def" +}; + const char *clang::getTraitName(TypeTrait T) { assert(T <= TT_Last && "invalid enum value!"); return TypeTraitNames[T]; @@ -84,3 +93,8 @@ const char *clang::getTraitSpelling(UnaryExprOrTypeTrait T) { assert(T <= UETT_Last && "invalid enum value!"); return UnaryExprOrTypeTraitSpellings[T]; } + +unsigned clang::getTypeTraitArity(TypeTrait T) { + assert(T <= TT_Last && "invalid enum value!"); + return TypeTraitArities[T]; +} diff --git a/contrib/llvm-project/clang/lib/Basic/Version.cpp b/contrib/llvm-project/clang/lib/Basic/Version.cpp index af3118b0f6da..4823f566bd77 100644 --- a/contrib/llvm-project/clang/lib/Basic/Version.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Version.cpp @@ -57,6 +57,14 @@ std::string getLLVMRevision() { #endif } +std::string getClangVendor() { +#ifdef CLANG_VENDOR + return CLANG_VENDOR; +#else + return ""; +#endif +} + std::string getClangFullRepositoryVersion() { std::string buf; llvm::raw_string_ostream OS(buf); @@ -82,7 +90,7 @@ std::string getClangFullRepositoryVersion() { OS << LLVMRepo << ' '; OS << LLVMRev << ')'; } - return OS.str(); + return buf; } std::string getClangFullVersion() { @@ -92,17 +100,14 @@ std::string getClangFullVersion() { std::string getClangToolFullVersion(StringRef ToolName) { std::string buf; llvm::raw_string_ostream OS(buf); -#ifdef CLANG_VENDOR - OS << CLANG_VENDOR; -#endif - OS << ToolName << " version " CLANG_VERSION_STRING; + OS << getClangVendor() << ToolName << " version " CLANG_VERSION_STRING; std::string repo = getClangFullRepositoryVersion(); if (!repo.empty()) { OS << " " << repo; } - return OS.str(); + return buf; } std::string getClangFullCPPVersion() { @@ -110,17 +115,14 @@ std::string getClangFullCPPVersion() { // the one we report on the command line. std::string buf; llvm::raw_string_ostream OS(buf); -#ifdef CLANG_VENDOR - OS << CLANG_VENDOR; -#endif - OS << "Clang " CLANG_VERSION_STRING; + OS << getClangVendor() << "Clang " CLANG_VERSION_STRING; std::string repo = getClangFullRepositoryVersion(); if (!repo.empty()) { OS << " " << repo; } - return OS.str(); + return buf; } } // end namespace clang diff --git a/contrib/llvm-project/clang/lib/Basic/Warnings.cpp b/contrib/llvm-project/clang/lib/Basic/Warnings.cpp index cc8c138233ca..5a5ac5556338 100644 --- a/contrib/llvm-project/clang/lib/Basic/Warnings.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Warnings.cpp @@ -96,11 +96,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, // Check to see if this warning starts with "no-", if so, this is a // negative form of the option. - bool isPositive = true; - if (Opt.startswith("no-")) { - isPositive = false; - Opt = Opt.substr(3); - } + bool isPositive = !Opt.consume_front("no-"); // Figure out how this option affects the warning. If -Wfoo, map the // diagnostic to a warning, if -Wno-foo, map it to ignore. @@ -133,7 +129,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, // table. It also has the "specifier" form of -Werror=foo. GCC supports // the deprecated -Werror-implicit-function-declaration which is used by // a few projects. - if (Opt.startswith("error")) { + if (Opt.starts_with("error")) { StringRef Specifier; if (Opt.size() > 5) { // Specifier must be present. if (Opt[5] != '=' && @@ -162,7 +158,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, } // -Wfatal-errors is yet another special case. - if (Opt.startswith("fatal-errors")) { + if (Opt.starts_with("fatal-errors")) { StringRef Specifier; if (Opt.size() != 12) { if ((Opt[12] != '=' && Opt[12] != '-') || Opt.size() == 13) { @@ -198,14 +194,12 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, } } - for (unsigned i = 0, e = Opts.Remarks.size(); i != e; ++i) { - StringRef Opt = Opts.Remarks[i]; + for (StringRef Opt : Opts.Remarks) { const auto Flavor = diag::Flavor::Remark; // Check to see if this warning starts with "no-", if so, this is a // negative form of the option. - bool IsPositive = !Opt.startswith("no-"); - if (!IsPositive) Opt = Opt.substr(3); + bool IsPositive = !Opt.consume_front("no-"); auto Severity = IsPositive ? diag::Severity::Remark : diag::Severity::Ignored; |