diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 7be4022649329..cd584d9621a22 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -6678,7 +6678,6 @@ class PseudoObjectExpr final class AtomicExpr : public Expr { public: enum AtomicOp { -#define BUILTIN(ID, TYPE, ATTRS) #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) AO ## ID, #include "clang/Basic/Builtins.inc" // Avoid trailing comma @@ -6742,7 +6741,6 @@ class AtomicExpr : public Expr { AtomicOp getOp() const { return Op; } StringRef getOpAsString() const { switch (Op) { -#define BUILTIN(ID, TYPE, ATTRS) #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ case AO##ID: \ return #ID; diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h index 63559d977ce6b..6d29b4315e5a7 100644 --- a/clang/include/clang/Basic/Builtins.h +++ b/clang/include/clang/Basic/Builtins.h @@ -18,6 +18,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringTable.h" #include // VC++ defines 'alloca' as an object-like macro, which interferes with our @@ -55,6 +56,7 @@ struct HeaderDesc { #undef HEADER } ID; + constexpr HeaderDesc() : ID() {} constexpr HeaderDesc(HeaderID ID) : ID(ID) {} const char *getName() const; @@ -62,20 +64,160 @@ struct HeaderDesc { namespace Builtin { enum ID { - NotBuiltin = 0, // This is not a builtin function. -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, + NotBuiltin = 0, // This is not a builtin function. +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/Builtins.inc" +#undef GET_BUILTIN_ENUMERATORS FirstTSBuiltin }; +struct InfosShard; + +/// The info used to represent each builtin. struct Info { - llvm::StringLiteral Name; - const char *Type, *Attributes; - const char *Features; - HeaderDesc Header; - LanguageID Langs; + // Rather than store pointers to the string literals describing these four + // aspects of builtins, we store offsets into a common string table. + struct StrOffsets { + llvm::StringTable::Offset Name = {}; + llvm::StringTable::Offset Type = {}; + llvm::StringTable::Offset Attributes = {}; + + // Defaults to the empty string offset. + llvm::StringTable::Offset Features = {}; + } Offsets; + + HeaderDesc Header = HeaderDesc::NO_HEADER; + LanguageID Langs = ALL_LANGUAGES; + + /// Get the name for the builtin represented by this `Info` object. + /// + /// Must be provided the `Shard` for this `Info` object. + std::string getName(const InfosShard &Shard) const; }; +/// A constexpr function to construct an infos array from X-macros. +/// +/// The input array uses the same data structure, but the offsets are actually +/// _lengths_ when input. This is all we can compute from the X-macro approach +/// to builtins. This function will convert these lengths into actual offsets to +/// a string table built up through sequentially appending strings with the +/// given lengths. +template +static constexpr std::array MakeInfos(std::array Infos) { + // Translate lengths to offsets. We start past the initial empty string at + // offset zero. + unsigned Offset = 1; + for (Info &I : Infos) { + Info::StrOffsets NewOffsets = {}; + NewOffsets.Name = Offset; + Offset += I.Offsets.Name.value(); + NewOffsets.Type = Offset; + Offset += I.Offsets.Type.value(); + NewOffsets.Attributes = Offset; + Offset += I.Offsets.Attributes.value(); + NewOffsets.Features = Offset; + Offset += I.Offsets.Features.value(); + I.Offsets = NewOffsets; + } + return Infos; +} + +/// A shard of a target's builtins string table and info. +/// +/// Target builtins are sharded across multiple tables due to different +/// structures, origins, and also to improve the overall scaling by avoiding a +/// single table across all builtins. +struct InfosShard { + const llvm::StringTable *Strings; + llvm::ArrayRef Infos; + + llvm::StringLiteral NamePrefix = ""; +}; + +// A detail macro used below to emit a string literal that, after string literal +// concatenation, ends up triggering the `-Woverlength-strings` warning. While +// the warning is useful in general to catch accidentally excessive strings, +// here we are creating them intentionally. +// +// This relies on a subtle aspect of `_Pragma`: that the *diagnostic* ones don't +// turn into actual tokens that would disrupt string literal concatenation. +#ifdef __clang__ +#define CLANG_BUILTIN_DETAIL_STR_TABLE(S) \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Woverlength-strings\"") \ + S _Pragma("clang diagnostic pop") +#else +#define CLANG_BUILTIN_DETAIL_STR_TABLE(S) S +#endif + +// We require string tables to start with an empty string so that a `0` offset +// can always be used to refer to an empty string. To satisfy that when building +// string tables with X-macros, we use this start macro prior to expanding the +// X-macros. +#define CLANG_BUILTIN_STR_TABLE_START CLANG_BUILTIN_DETAIL_STR_TABLE("\0") + +// A macro that can be used with `Builtins.def` and similar files as an X-macro +// to add the string arguments to a builtin string table. This is typically the +// target for the `BUILTIN`, `LANGBUILTIN`, or `LIBBUILTIN` macros in those +// files. +#define CLANG_BUILTIN_STR_TABLE(ID, TYPE, ATTRS) \ + CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" /*FEATURE*/ "\0") + +// A macro that can be used with target builtin `.def` and `.inc` files as an +// X-macro to add the string arguments to a builtin string table. this is +// typically the target for the `TARGET_BUILTIN` macro. +#define CLANG_TARGET_BUILTIN_STR_TABLE(ID, TYPE, ATTRS, FEATURE) \ + CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" FEATURE "\0") + +// A macro that can be used with target builtin `.def` and `.inc` files as an +// X-macro to add the string arguments to a builtin string table. this is +// typically the target for the `TARGET_HEADER_BUILTIN` macro. We can't delegate +// to `TARGET_BUILTIN` because the `FEATURE` string changes position. +#define CLANG_TARGET_HEADER_BUILTIN_STR_TABLE(ID, TYPE, ATTRS, HEADER, LANGS, \ + FEATURE) \ + CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" FEATURE "\0") + +// A detail macro used internally to compute the desired string table +// `StrOffsets` struct for arguments to `MakeInfos`. +#define CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS) \ + Builtin::Info::StrOffsets { \ + sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("") \ + } + +// A detail macro used internally to compute the desired string table +// `StrOffsets` struct for arguments to `Storage::Make`. +#define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE) \ + Builtin::Info::StrOffsets { \ + sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof(FEATURE) \ + } + +// A set of macros that can be used with builtin `.def' files as an X-macro to +// create an `Info` struct for a particular builtin. It both computes the +// `StrOffsets` value for the string table (the lengths here, translated to +// offsets by the `MakeInfos` function), and the other metadata for each +// builtin. +// +// There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`, +// `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`. +#define CLANG_BUILTIN_ENTRY(ID, TYPE, ATTRS) \ + Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS), \ + HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#define CLANG_LANGBUILTIN_ENTRY(ID, TYPE, ATTRS, LANG) \ + Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS), \ + HeaderDesc::NO_HEADER, LANG}, +#define CLANG_LIBBUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG) \ + Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS), \ + HeaderDesc::HEADER, LANG}, +#define CLANG_TARGET_BUILTIN_ENTRY(ID, TYPE, ATTRS, FEATURE) \ + Builtin::Info{ \ + CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE), \ + HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#define CLANG_TARGET_HEADER_BUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG, \ + FEATURE) \ + Builtin::Info{ \ + CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE), \ + HeaderDesc::HEADER, LANG}, + /// Holds information about both target-independent and /// target-specific builtins, allowing easy queries by clients. /// @@ -83,11 +225,16 @@ struct Info { /// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to /// be translated back with getAuxBuiltinID() before use. class Context { - llvm::ArrayRef TSRecords; - llvm::ArrayRef AuxTSRecords; + llvm::SmallVector BuiltinShards; + + llvm::SmallVector TargetShards; + llvm::SmallVector AuxTargetShards; + + unsigned NumTargetBuiltins = 0; + unsigned NumAuxTargetBuiltins = 0; public: - Context() = default; + Context(); /// Perform target-specific initialization /// \param AuxTarget Target info to incorporate builtins from. May be nullptr. @@ -100,13 +247,17 @@ class Context { /// Return the identifier name for the specified builtin, /// e.g. "__builtin_abs". - llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; } + std::string getName(unsigned ID) const; - /// Return a quoted name for the specified builtin for use in diagnostics. + /// Return the identifier name for the specified builtin inside single quotes + /// for a diagnostic, e.g. "'__builtin_abs'". std::string getQuotedName(unsigned ID) const; /// Get the type descriptor string for the specified builtin. - const char *getTypeString(unsigned ID) const { return getRecord(ID).Type; } + const char *getTypeString(unsigned ID) const; + + /// Get the attributes descriptor string for the specified builtin. + const char *getAttributesString(unsigned ID) const; /// Return true if this function is a target-specific builtin. bool isTSBuiltin(unsigned ID) const { @@ -115,40 +266,40 @@ class Context { /// Return true if this function has no side effects. bool isPure(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'U') != nullptr; + return strchr(getAttributesString(ID), 'U') != nullptr; } /// Return true if this function has no side effects and doesn't /// read memory. bool isConst(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'c') != nullptr; + return strchr(getAttributesString(ID), 'c') != nullptr; } /// Return true if we know this builtin never throws an exception. bool isNoThrow(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'n') != nullptr; + return strchr(getAttributesString(ID), 'n') != nullptr; } /// Return true if we know this builtin never returns. bool isNoReturn(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'r') != nullptr; + return strchr(getAttributesString(ID), 'r') != nullptr; } /// Return true if we know this builtin can return twice. bool isReturnsTwice(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'j') != nullptr; + return strchr(getAttributesString(ID), 'j') != nullptr; } /// Returns true if this builtin does not perform the side-effects /// of its arguments. bool isUnevaluated(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'u') != nullptr; + return strchr(getAttributesString(ID), 'u') != nullptr; } /// Return true if this is a builtin for a libc/libm function, /// with a "__builtin_" prefix (e.g. __builtin_abs). bool isLibFunction(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'F') != nullptr; + return strchr(getAttributesString(ID), 'F') != nullptr; } /// Determines whether this builtin is a predefined libc/libm @@ -159,21 +310,21 @@ class Context { /// they do not, but they are recognized as builtins once we see /// a declaration. bool isPredefinedLibFunction(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'f') != nullptr; + return strchr(getAttributesString(ID), 'f') != nullptr; } /// Returns true if this builtin requires appropriate header in other /// compilers. In Clang it will work even without including it, but we can emit /// a warning about missing header. bool isHeaderDependentFunction(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'h') != nullptr; + return strchr(getAttributesString(ID), 'h') != nullptr; } /// Determines whether this builtin is a predefined compiler-rt/libgcc /// function, such as "__clear_cache", where we know the signature a /// priori. bool isPredefinedRuntimeFunction(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'i') != nullptr; + return strchr(getAttributesString(ID), 'i') != nullptr; } /// Determines whether this builtin is a C++ standard library function @@ -181,7 +332,7 @@ class Context { /// specialization, where the signature is determined by the standard library /// declaration. bool isInStdNamespace(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'z') != nullptr; + return strchr(getAttributesString(ID), 'z') != nullptr; } /// Determines whether this builtin can have its address taken with no @@ -195,33 +346,33 @@ class Context { /// Determines whether this builtin has custom typechecking. bool hasCustomTypechecking(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 't') != nullptr; + return strchr(getAttributesString(ID), 't') != nullptr; } /// Determines whether a declaration of this builtin should be recognized /// even if the type doesn't match the specified signature. bool allowTypeMismatch(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'T') != nullptr || + return strchr(getAttributesString(ID), 'T') != nullptr || hasCustomTypechecking(ID); } /// Determines whether this builtin has a result or any arguments which /// are pointer types. bool hasPtrArgsOrResult(unsigned ID) const { - return strchr(getRecord(ID).Type, '*') != nullptr; + return strchr(getTypeString(ID), '*') != nullptr; } /// Return true if this builtin has a result or any arguments which are /// reference types. bool hasReferenceArgsOrResult(unsigned ID) const { - return strchr(getRecord(ID).Type, '&') != nullptr || - strchr(getRecord(ID).Type, 'A') != nullptr; + return strchr(getTypeString(ID), '&') != nullptr || + strchr(getTypeString(ID), 'A') != nullptr; } /// If this is a library function that comes from a specific /// header, retrieve that header name. const char *getHeaderName(unsigned ID) const { - return getRecord(ID).Header.getName(); + return getInfo(ID).Header.getName(); } /// Determine whether this builtin is like printf in its @@ -246,27 +397,25 @@ class Context { /// Such functions can be const when the MathErrno lang option and FP /// exceptions are disabled. bool isConstWithoutErrnoAndExceptions(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'e') != nullptr; + return strchr(getAttributesString(ID), 'e') != nullptr; } bool isConstWithoutExceptions(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'g') != nullptr; + return strchr(getAttributesString(ID), 'g') != nullptr; } - const char *getRequiredFeatures(unsigned ID) const { - return getRecord(ID).Features; - } + const char *getRequiredFeatures(unsigned ID) const; unsigned getRequiredVectorWidth(unsigned ID) const; /// Return true if builtin ID belongs to AuxTarget. bool isAuxBuiltinID(unsigned ID) const { - return ID >= (Builtin::FirstTSBuiltin + TSRecords.size()); + return ID >= (Builtin::FirstTSBuiltin + NumTargetBuiltins); } /// Return real builtin ID (i.e. ID it would have during compilation /// for AuxTarget). - unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); } + unsigned getAuxBuiltinID(unsigned ID) const { return ID - NumTargetBuiltins; } /// Returns true if this is a libc/libm function without the '__builtin_' /// prefix. @@ -278,16 +427,19 @@ class Context { /// Return true if this function can be constant evaluated by Clang frontend. bool isConstantEvaluated(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'E') != nullptr; + return strchr(getAttributesString(ID), 'E') != nullptr; } /// Returns true if this is an immediate (consteval) function bool isImmediate(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'G') != nullptr; + return strchr(getAttributesString(ID), 'G') != nullptr; } private: - const Info &getRecord(unsigned ID) const; + std::pair + getShardAndInfo(unsigned ID) const; + + const Info &getInfo(unsigned ID) const { return getShardAndInfo(ID).second; } /// Helper function for isPrintfLike and isScanfLike. bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg, diff --git a/clang/include/clang/Basic/BuiltinsARM.def b/clang/include/clang/Basic/BuiltinsARM.def index 5a7064a98045e..cbab87cecbc7d 100644 --- a/clang/include/clang/Basic/BuiltinsARM.def +++ b/clang/include/clang/Basic/BuiltinsARM.def @@ -206,13 +206,6 @@ BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc") // Misc BUILTIN(__builtin_sponentry, "v*", "c") -// Builtins for implementing ACLE MVE intrinsics. (Unlike NEON, these -// don't need to live in a separate BuiltinsMVE.def, because they -// aren't included from both here and BuiltinsAArch64.def.) -#include "clang/Basic/arm_mve_builtins.inc" - -#include "clang/Basic/arm_cde_builtins.inc" - // MSVC LANGBUILTIN(__emit, "vIUiC", "", ALL_MS_LANGUAGES) diff --git a/clang/include/clang/Basic/BuiltinsBase.td b/clang/include/clang/Basic/BuiltinsBase.td index 6180a94aa4b5c..cf15a31235e7e 100644 --- a/clang/include/clang/Basic/BuiltinsBase.td +++ b/clang/include/clang/Basic/BuiltinsBase.td @@ -86,6 +86,13 @@ def Consteval : Attribute<"EG">; // indicated by the remaining indices. class Callback ArgIndices> : MultiIndexAttribute<"C", ArgIndices>; +// Prefixes +// ======== + +class NamePrefix { + string Spelling = spelling; +} + // Builtin kinds // ============= @@ -99,6 +106,9 @@ class Builtin { bit RequiresUndef = 0; // Enables builtins to generate `long long` outside of OpenCL and `long` inside. bit EnableOpenCLLong = 0; + // Requires a common prefix to be prepended. Each generated set of builtins + // can optionally extract one common prefix that is handled separately. + NamePrefix RequiredNamePrefix; } class AtomicBuiltin : Builtin; diff --git a/clang/include/clang/Basic/BuiltinsHexagon.td b/clang/include/clang/Basic/BuiltinsHexagon.td index 95b9012bf74f9..0727c67346697 100644 --- a/clang/include/clang/Basic/BuiltinsHexagon.td +++ b/clang/include/clang/Basic/BuiltinsHexagon.td @@ -56,10 +56,13 @@ def HVXV65 : HVXV<"65", HVXV66>; def HVXV62 : HVXV<"62", HVXV65>; def HVXV60 : HVXV<"60", HVXV62>; +def HexagonPrefix : NamePrefix<"__builtin_HEXAGON_">; + class HexagonBuiltin : TargetBuiltin { - let Spellings = ["__builtin_HEXAGON_" # NAME]; + let Spellings = [NAME]; let Prototype = prototype; let Features = V5.Features; + let RequiredNamePrefix = HexagonPrefix; // Adds a prefix to the name. } class HexagonBuiltinNoPrefix : TargetBuiltin { diff --git a/clang/include/clang/Basic/BuiltinsLoongArch.def b/clang/include/clang/Basic/BuiltinsLoongArch.def deleted file mode 100644 index 95359a3fdc711..0000000000000 --- a/clang/include/clang/Basic/BuiltinsLoongArch.def +++ /dev/null @@ -1,28 +0,0 @@ -//==- BuiltinsLoongArch.def - LoongArch Builtin function database -- 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 defines the LoongArch-specific builtin function database. Users of -// this file must define the BUILTIN macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -#if defined(BUILTIN) && !defined(TARGET_BUILTIN) -# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) -#endif - -// Definition of LoongArch basic builtins. -#include "clang/Basic/BuiltinsLoongArchBase.def" - -// Definition of LSX builtins. -#include "clang/Basic/BuiltinsLoongArchLSX.def" - -// Definition of LASX builtins. -#include "clang/Basic/BuiltinsLoongArchLASX.def" - -#undef BUILTIN -#undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsNEON.def b/clang/include/clang/Basic/BuiltinsNEON.def deleted file mode 100644 index 9627005ba9824..0000000000000 --- a/clang/include/clang/Basic/BuiltinsNEON.def +++ /dev/null @@ -1,22 +0,0 @@ -//===--- BuiltinsNEON.def - NEON Builtin function database ------*- 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 defines the NEON-specific builtin function database. Users of -// this file must define the BUILTIN macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -// The format of this database matches clang/Basic/Builtins.def. - -#define GET_NEON_BUILTINS -#include "clang/Basic/arm_neon.inc" -#include "clang/Basic/arm_fp16.inc" -#undef GET_NEON_BUILTINS - -#undef BUILTIN -#undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index 161df386f00f0..bb7d54bbb793e 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -1138,5 +1138,6 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true, // FIXME: Obviously incomplete. #undef BUILTIN +#undef TARGET_BUILTIN #undef CUSTOM_BUILTIN #undef UNALIASED_CUSTOM_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsRISCVVector.def b/clang/include/clang/Basic/BuiltinsRISCVVector.def deleted file mode 100644 index 6dfa87a1a1d31..0000000000000 --- a/clang/include/clang/Basic/BuiltinsRISCVVector.def +++ /dev/null @@ -1,22 +0,0 @@ -//==- BuiltinsRISCVVector.def - RISC-V Vector Builtin Database ---*- 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 defines the RISC-V-specific builtin function database. Users of -// this file must define the BUILTIN macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -#if defined(BUILTIN) && !defined(TARGET_BUILTIN) -# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) -#endif - -#include "clang/Basic/riscv_vector_builtins.inc" -#include "clang/Basic/riscv_sifive_vector_builtins.inc" - -#undef BUILTIN -#undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsX86Base.td b/clang/include/clang/Basic/BuiltinsX86Base.td index aca39c204516a..0d739ee0b0b69 100644 --- a/clang/include/clang/Basic/BuiltinsX86Base.td +++ b/clang/include/clang/Basic/BuiltinsX86Base.td @@ -12,10 +12,13 @@ include "clang/Basic/BuiltinsBase.td" +def X86Prefix : NamePrefix<"__builtin_ia32_">; + class X86Builtin : TargetBuiltin { - let Spellings = ["__builtin_ia32_" # NAME]; + let Spellings = [NAME]; let Prototype = prototype; let EnableOpenCLLong = 1; + let RequiredNamePrefix = X86Prefix; // Adds a prefix to the name. } class X86NoPrefixBuiltin : TargetBuiltin { diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index e5e6be3c96600..0347880244a40 100644 --- a/clang/include/clang/Basic/IdentifierTable.h +++ b/clang/include/clang/Basic/IdentifierTable.h @@ -101,8 +101,9 @@ enum class InterestingIdentifier { NUM_OBJC_KEYWORDS_AND_NOTABLE_IDENTIFIERS, NotBuiltin, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/Builtins.inc" +#undef GET_BUILTIN_ENUMERATORS FirstTSBuiltin, NotInterestingIdentifier = 65534 diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 95eb110bb9c24..4781054240b5b 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -26,30 +26,50 @@ namespace clang { namespace NEON { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID, -#include "clang/Basic/BuiltinsNEON.def" +#define GET_NEON_BUILTIN_ENUMERATORS +#include "clang/Basic/arm_neon.inc" + FirstFp16Builtin, + LastNeonBuiltin = FirstFp16Builtin - 1, +#include "clang/Basic/arm_fp16.inc" +#undef GET_NEON_BUILTIN_ENUMERATORS FirstTSBuiltin }; } /// ARM builtins namespace ARM { - enum { - LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, - LastNEONBuiltin = NEON::FirstTSBuiltin - 1, + enum { + LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, + LastNEONBuiltin = NEON::FirstTSBuiltin - 1, +#define GET_MVE_BUILTIN_ENUMERATORS +#include "clang/Basic/arm_mve_builtins.inc" +#undef GET_MVE_BUILTIN_ENUMERATORS + FirstCDEBuiltin, + LastMVEBuiltin = FirstCDEBuiltin - 1, +#define GET_CDE_BUILTIN_ENUMERATORS +#include "clang/Basic/arm_cde_builtins.inc" +#undef GET_CDE_BUILTIN_ENUMERATORS + FirstARMBuiltin, + LastCDEBuiltin = FirstARMBuiltin - 1, #define BUILTIN(ID, TYPE, ATTRS) BI##ID, #include "clang/Basic/BuiltinsARM.def" - LastTSBuiltin - }; + LastTSBuiltin + }; } namespace SVE { enum { LastNEONBuiltin = NEON::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_SVE_BUILTIN_ENUMERATORS +#include "clang/Basic/arm_sve_builtins.inc" +#undef GET_SVE_BUILTIN_ENUMERATORS + FirstNeonBridgeBuiltin, + LastSveBuiltin = FirstNeonBridgeBuiltin - 1, +#define GET_SVE_BUILTINS #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID, -#include "clang/Basic/BuiltinsSVE.def" +#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def" +#undef TARGET_BUILTIN +#undef GET_SVE_BUILTINS FirstTSBuiltin, }; } @@ -57,9 +77,9 @@ namespace clang { namespace SME { enum { LastSVEBuiltin = SVE::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID, -#include "clang/Basic/BuiltinsSME.def" +#define GET_SME_BUILTIN_ENUMERATORS +#include "clang/Basic/arm_sme_builtins.inc" +#undef GET_SME_BUILTIN_ENUMERATORS FirstTSBuiltin, }; } @@ -83,8 +103,9 @@ namespace clang { namespace BPF { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, - #define BUILTIN(ID, TYPE, ATTRS) BI##ID, - #include "clang/Basic/BuiltinsBPF.inc" +#define GET_BUILTIN_ENUMERATORS +#include "clang/Basic/BuiltinsBPF.inc" +#undef GET_BUILTIN_ENUMERATORS LastTSBuiltin }; } @@ -103,8 +124,9 @@ namespace clang { namespace NVPTX { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/BuiltinsNVPTX.inc" +#undef GET_BUILTIN_ENUMERATORS LastTSBuiltin }; } @@ -123,8 +145,9 @@ namespace clang { namespace SPIRV { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/BuiltinsSPIRV.inc" +#undef GET_BUILTIN_ENUMERATORS LastTSBuiltin }; } // namespace SPIRV @@ -133,12 +156,14 @@ namespace clang { namespace X86 { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/BuiltinsX86.inc" +#undef GET_BUILTIN_ENUMERATORS FirstX86_64Builtin, LastX86CommonBuiltin = FirstX86_64Builtin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/BuiltinsX86_64.inc" +#undef GET_BUILTIN_ENUMERATORS LastTSBuiltin }; } @@ -156,8 +181,12 @@ namespace clang { namespace RISCVVector { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, -#include "clang/Basic/BuiltinsRISCVVector.def" +#define GET_RISCVV_BUILTIN_ENUMERATORS +#include "clang/Basic/riscv_vector_builtins.inc" + FirstSiFiveBuiltin, + LastRVVBuiltin = FirstSiFiveBuiltin - 1, +#include "clang/Basic/riscv_sifive_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_ENUMERATORS FirstTSBuiltin, }; } @@ -168,8 +197,9 @@ namespace clang { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, FirstRVVBuiltin = clang::Builtin::FirstTSBuiltin, LastRVVBuiltin = RISCVVector::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/BuiltinsRISCV.inc" +#undef GET_BUILTIN_ENUMERATORS LastTSBuiltin }; } // namespace RISCV @@ -178,8 +208,16 @@ namespace clang { namespace LoongArch { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, -#include "clang/Basic/BuiltinsLoongArch.def" +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID, +#include "clang/Basic/BuiltinsLoongArchBase.def" + FirstLSXBuiltin, + LastBaseBuiltin = FirstLSXBuiltin - 1, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID, +#include "clang/Basic/BuiltinsLoongArchLSX.def" + FirstLASXBuiltin, + LastLSXBuiltin = FirstLASXBuiltin - 1, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID, +#include "clang/Basic/BuiltinsLoongArchLASX.def" LastTSBuiltin }; } // namespace LoongArch @@ -356,8 +394,9 @@ namespace clang { namespace Hexagon { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/BuiltinsHexagon.inc" +#undef GET_BUILTIN_ENUMERATORS LastTSBuiltin }; } diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index d762144478b48..77c2f88a172d9 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -16,6 +16,7 @@ #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/BitmaskEnum.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/CFProtectionOptions.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/LLVM.h" @@ -32,6 +33,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" +#include "llvm/ADT/StringTable.h" #include "llvm/Frontend/OpenMP/OMPGridValues.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/Support/DataTypes.h" @@ -1016,10 +1018,10 @@ class TargetInfo : public TransferrableTargetInfo, virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const = 0; - /// Return information about target-specific builtins for - /// the current primary target, and info about which builtins are non-portable - /// across the current set of primary and secondary targets. - virtual ArrayRef getTargetBuiltins() const = 0; + /// Return information about target-specific builtins for the current primary + /// target, and info about which builtins are non-portable across the current + /// set of primary and secondary targets. + virtual llvm::SmallVector getTargetBuiltins() const = 0; /// Returns target-specific min and max values VScale_Range. virtual std::optional> diff --git a/clang/include/module.modulemap b/clang/include/module.modulemap index b318bd95ee67c..e2bc941d3143a 100644 --- a/clang/include/module.modulemap +++ b/clang/include/module.modulemap @@ -45,7 +45,6 @@ module Clang_Basic { textual header "clang/Basic/BuiltinsAMDGPU.def" textual header "clang/Basic/BuiltinsARM.def" textual header "clang/Basic/BuiltinsHexagonMapCustomDep.def" - textual header "clang/Basic/BuiltinsLoongArch.def" textual header "clang/Basic/BuiltinsLoongArchBase.def" textual header "clang/Basic/BuiltinsLoongArchLASX.def" textual header "clang/Basic/BuiltinsLoongArchLSX.def" diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index bae4134e28359..3ce932a9dd352 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1977,7 +1977,6 @@ void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) { void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) { const char *Name = nullptr; switch (Node->getOp()) { -#define BUILTIN(ID, TYPE, ATTRS) #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ case AtomicExpr::AO ## ID: \ Name = #ID "("; \ diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp index 588183788de32..e7829a461bbc5 100644 --- a/clang/lib/Basic/Builtins.cpp +++ b/clang/lib/Basic/Builtins.cpp @@ -29,54 +29,120 @@ const char *HeaderDesc::getName() const { 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, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS}, +static constexpr unsigned NumBuiltins = Builtin::FirstTSBuiltin; + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/Builtins.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { + Builtin::Info{}, // No-builtin info entry. +#define GET_BUILTIN_INFOS #include "clang/Basic/Builtins.inc" +#undef GET_BUILTIN_INFOS }; +static_assert(std::size(BuiltinInfos) == NumBuiltins); -const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const { - if (ID < Builtin::FirstTSBuiltin) - return BuiltinInfo[ID]; - assert(((ID - Builtin::FirstTSBuiltin) < - (TSRecords.size() + AuxTSRecords.size())) && +std::pair +Builtin::Context::getShardAndInfo(unsigned ID) const { + assert((ID < (Builtin::FirstTSBuiltin + NumTargetBuiltins + + NumAuxTargetBuiltins)) && "Invalid builtin ID!"); - if (isAuxBuiltinID(ID)) - return AuxTSRecords[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin]; - return TSRecords[ID - Builtin::FirstTSBuiltin]; + + ArrayRef Shards = BuiltinShards; + if (isAuxBuiltinID(ID)) { + Shards = AuxTargetShards; + ID = getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin; + } else if (ID >= Builtin::FirstTSBuiltin) { + Shards = TargetShards; + ID -= Builtin::FirstTSBuiltin; + } + + // Loop over the shards to find the one matching this ID. We don't expect to + // have many shards and so its better to search linearly than with a binary + // search. + for (const auto &Shard : Shards) { + if (ID < Shard.Infos.size()) { + return {Shard, Shard.Infos[ID]}; + } + + ID -= Shard.Infos.size(); + } + llvm_unreachable("Invalid target builtin shard structure!"); +} + +std::string Builtin::Info::getName(const Builtin::InfosShard &Shard) const { + return (Twine(Shard.NamePrefix) + (*Shard.Strings)[Offsets.Name]).str(); +} + +/// Return the identifier name for the specified builtin, +/// e.g. "__builtin_abs". +std::string Builtin::Context::getName(unsigned ID) const { + const auto &[Shard, I] = getShardAndInfo(ID); + return I.getName(Shard); +} + +std::string Builtin::Context::getQuotedName(unsigned ID) const { + const auto &[Shard, I] = getShardAndInfo(ID); + return (Twine("'") + Shard.NamePrefix + (*Shard.Strings)[I.Offsets.Name] + + "'") + .str(); +} + +const char *Builtin::Context::getTypeString(unsigned ID) const { + const auto &[Shard, I] = getShardAndInfo(ID); + return (*Shard.Strings)[I.Offsets.Type].data(); } +const char *Builtin::Context::getAttributesString(unsigned ID) const { + const auto &[Shard, I] = getShardAndInfo(ID); + return (*Shard.Strings)[I.Offsets.Attributes].data(); +} + +const char *Builtin::Context::getRequiredFeatures(unsigned ID) const { + const auto &[Shard, I] = getShardAndInfo(ID); + return (*Shard.Strings)[I.Offsets.Features].data(); +} + +Builtin::Context::Context() : BuiltinShards{{&BuiltinStrings, BuiltinInfos}} {} + void Builtin::Context::InitializeTarget(const TargetInfo &Target, const TargetInfo *AuxTarget) { - assert(TSRecords.empty() && "Already initialized target?"); - TSRecords = Target.getTargetBuiltins(); - if (AuxTarget) - AuxTSRecords = AuxTarget->getTargetBuiltins(); + assert(TargetShards.empty() && "Already initialized target?"); + assert(NumTargetBuiltins == 0 && "Already initialized target?"); + TargetShards = Target.getTargetBuiltins(); + for (const auto &Shard : TargetShards) + NumTargetBuiltins += Shard.Infos.size(); + if (AuxTarget) { + AuxTargetShards = AuxTarget->getTargetBuiltins(); + for (const auto &Shard : AuxTargetShards) + NumAuxTargetBuiltins += Shard.Infos.size(); + } } bool Builtin::Context::isBuiltinFunc(llvm::StringRef FuncName) { bool InStdNamespace = FuncName.consume_front("std-"); - for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin; - ++i) { - if (FuncName == BuiltinInfo[i].Name && - (bool)strchr(BuiltinInfo[i].Attributes, 'z') == InStdNamespace) - return strchr(BuiltinInfo[i].Attributes, 'f') != nullptr; - } + for (const auto &Shard : {InfosShard{&BuiltinStrings, BuiltinInfos}}) + if (llvm::StringRef FuncNameSuffix = FuncName; + FuncNameSuffix.consume_front(Shard.NamePrefix)) + for (const auto &I : Shard.Infos) + if (FuncNameSuffix == (*Shard.Strings)[I.Offsets.Name] && + (bool)strchr((*Shard.Strings)[I.Offsets.Attributes].data(), 'z') == + InStdNamespace) + return strchr((*Shard.Strings)[I.Offsets.Attributes].data(), 'f') != + nullptr; return false; } /// Is this builtin supported according to the given language options? -static bool builtinIsSupported(const Builtin::Info &BuiltinInfo, +static bool builtinIsSupported(const llvm::StringTable &Strings, + const Builtin::Info &BuiltinInfo, const LangOptions &LangOpts) { + auto AttributesStr = Strings[BuiltinInfo.Offsets.Attributes]; + /* Builtins Unsupported */ - if (LangOpts.NoBuiltin && strchr(BuiltinInfo.Attributes, 'f') != nullptr) + if (LangOpts.NoBuiltin && strchr(AttributesStr.data(), 'f') != nullptr) return false; /* CorBuiltins Unsupported */ if (!LangOpts.Coroutines && (BuiltinInfo.Langs & COR_LANG)) @@ -123,7 +189,7 @@ static bool builtinIsSupported(const Builtin::Info &BuiltinInfo, if (!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG) return false; /* consteval Unsupported */ - if (!LangOpts.CPlusPlus20 && strchr(BuiltinInfo.Attributes, 'G') != nullptr) + if (!LangOpts.CPlusPlus20 && strchr(AttributesStr.data(), 'G') != nullptr) return false; return true; } @@ -132,22 +198,34 @@ static bool builtinIsSupported(const Builtin::Info &BuiltinInfo, /// appropriate builtin ID # and mark any non-portable builtin identifiers as /// such. void Builtin::Context::initializeBuiltins(IdentifierTable &Table, - const LangOptions& LangOpts) { - // Step #1: mark all target-independent builtins with their ID's. - for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin; ++i) - if (builtinIsSupported(BuiltinInfo[i], LangOpts)) { - Table.get(BuiltinInfo[i].Name).setBuiltinID(i); - } - - // Step #2: Register target-specific builtins. - for (unsigned i = 0, e = TSRecords.size(); i != e; ++i) - if (builtinIsSupported(TSRecords[i], LangOpts)) - Table.get(TSRecords[i].Name).setBuiltinID(i + Builtin::FirstTSBuiltin); + const LangOptions &LangOpts) { + { + unsigned ID = 0; + // Step #1: mark all target-independent builtins with their ID's. + for (const auto &Shard : BuiltinShards) + for (const auto &I : Shard.Infos) { + // If this is a real builtin (ID != 0) and is supported, add it. + if (ID != 0 && builtinIsSupported(*Shard.Strings, I, LangOpts)) + Table.get(I.getName(Shard)).setBuiltinID(ID); + ++ID; + } + assert(ID == FirstTSBuiltin && "Should have added all non-target IDs!"); + + // Step #2: Register target-specific builtins. + for (const auto &Shard : TargetShards) + for (const auto &I : Shard.Infos) { + if (builtinIsSupported(*Shard.Strings, I, LangOpts)) + Table.get(I.getName(Shard)).setBuiltinID(ID); + ++ID; + } - // Step #3: Register target-specific builtins for AuxTarget. - for (unsigned i = 0, e = AuxTSRecords.size(); i != e; ++i) - Table.get(AuxTSRecords[i].Name) - .setBuiltinID(i + Builtin::FirstTSBuiltin + TSRecords.size()); + // Step #3: Register target-specific builtins for AuxTarget. + for (const auto &Shard : AuxTargetShards) + for (const auto &I : Shard.Infos) { + Table.get(I.getName(Shard)).setBuiltinID(ID); + ++ID; + } + } // Step #4: Unregister any builtins specified by -fno-builtin-foo. for (llvm::StringRef Name : LangOpts.NoBuiltinFuncs) { @@ -163,12 +241,8 @@ void Builtin::Context::initializeBuiltins(IdentifierTable &Table, } } -std::string Builtin::Context::getQuotedName(unsigned ID) const { - return (llvm::Twine("'") + getName(ID) + "'").str(); -} - unsigned Builtin::Context::getRequiredVectorWidth(unsigned ID) const { - const char *WidthPos = ::strchr(getRecord(ID).Attributes, 'V'); + const char *WidthPos = ::strchr(getAttributesString(ID), 'V'); if (!WidthPos) return 0; @@ -191,7 +265,7 @@ bool Builtin::Context::isLike(unsigned ID, unsigned &FormatIdx, assert(::toupper(Fmt[0]) == Fmt[1] && "Format string is not in the form \"xX\""); - const char *Like = ::strpbrk(getRecord(ID).Attributes, Fmt); + const char *Like = ::strpbrk(getAttributesString(ID), Fmt); if (!Like) return false; @@ -218,7 +292,7 @@ bool Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx, bool Builtin::Context::performsCallback(unsigned ID, SmallVectorImpl &Encoding) const { - const char *CalleePos = ::strchr(getRecord(ID).Attributes, 'C'); + const char *CalleePos = ::strchr(getAttributesString(ID), 'C'); if (!CalleePos) return false; diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 57c9849ef2a72..049b8d6b54ca1 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -26,35 +26,105 @@ 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}, -#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, 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, 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, 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, FEATURE, HeaderDesc::HEADER, LANGS}, -#include "clang/Basic/BuiltinsAArch64.def" +static constexpr int NumNeonBuiltins = + NEON::FirstFp16Builtin - Builtin::FirstTSBuiltin; +static constexpr int NumFp16Builtins = + NEON::FirstTSBuiltin - NEON::FirstFp16Builtin; +static constexpr int NumSVEBuiltins = + SVE::FirstNeonBridgeBuiltin - NEON::FirstTSBuiltin; +static constexpr int NumSVENeonBridgeBuiltins = + SVE::FirstTSBuiltin - SVE::FirstNeonBridgeBuiltin; +static constexpr int NumSMEBuiltins = SME::FirstTSBuiltin - SVE::FirstTSBuiltin; +static constexpr int NumAArch64Builtins = + AArch64::LastTSBuiltin - SME::FirstTSBuiltin; +static constexpr int NumBuiltins = + AArch64::LastTSBuiltin - Builtin::FirstTSBuiltin; +static_assert(NumBuiltins == + (NumNeonBuiltins + NumFp16Builtins + NumSVEBuiltins + + NumSVENeonBridgeBuiltins + NumSMEBuiltins + NumAArch64Builtins)); + +namespace clang { +namespace NEON { +#define GET_NEON_BUILTIN_STR_TABLE +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_NEON_BUILTIN_INFOS +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_BUILTIN_INFOS +}; + +namespace FP16 { +#define GET_NEON_BUILTIN_STR_TABLE +#include "clang/Basic/arm_fp16.inc" +#undef GET_NEON_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_NEON_BUILTIN_INFOS +#include "clang/Basic/arm_fp16.inc" +#undef GET_NEON_BUILTIN_INFOS +}; +} // namespace FP16 +} // namespace NEON + +namespace SVE { +#define GET_SVE_BUILTIN_STR_TABLE +#include "clang/Basic/arm_sve_builtins.inc" +#undef GET_SVE_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_SVE_BUILTIN_INFOS +#include "clang/Basic/arm_sve_builtins.inc" +#undef GET_SVE_BUILTIN_INFOS }; +} // namespace SVE + +namespace SME { +#define GET_SME_BUILTIN_STR_TABLE +#include "clang/Basic/arm_sme_builtins.inc" +#undef GET_SME_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_SME_BUILTIN_INFOS +#include "clang/Basic/arm_sme_builtins.inc" +#undef GET_SME_BUILTIN_INFOS +}; +} // namespace SME +} // namespace clang + +static constexpr llvm::StringTable BuiltinSVENeonBridgeStrings = + CLANG_BUILTIN_STR_TABLE_START +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#define GET_SVE_BUILTINS +#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def" +#undef GET_SVE_BUILTINS +#undef TARGET_BUILTIN + ; +static constexpr llvm::StringTable BuiltinAArch64Strings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsAArch64.def" + ; + +static constexpr auto BuiltinSVENeonBridgeInfos = + Builtin::MakeInfos({ +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#define GET_SVE_BUILTINS +#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def" +#undef GET_SVE_BUILTINS +#undef TARGET_BUILTIN + }); +static constexpr auto BuiltinAArch64Infos = + Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY +#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsAArch64.def" + }); void AArch64TargetInfo::setArchFeatures() { if (*ArchInfo == llvm::AArch64::ARMV8R) { @@ -697,9 +767,17 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, } } -ArrayRef AArch64TargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin - - Builtin::FirstTSBuiltin); +llvm::SmallVector +AArch64TargetInfo::getTargetBuiltins() const { + return { + {&NEON::BuiltinStrings, NEON::BuiltinInfos, "__builtin_neon_"}, + {&NEON::FP16::BuiltinStrings, NEON::FP16::BuiltinInfos, + "__builtin_neon_"}, + {&SVE::BuiltinStrings, SVE::BuiltinInfos, "__builtin_sve_"}, + {&BuiltinSVENeonBridgeStrings, BuiltinSVENeonBridgeInfos}, + {&SME::BuiltinStrings, SME::BuiltinInfos, "__builtin_sme_"}, + {&BuiltinAArch64Strings, BuiltinAArch64Infos}, + }; } std::optional> diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 79e012f48e65b..f2510adb0ea22 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -181,7 +181,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; std::optional> getVScaleRange(const LangOptions &LangOpts, diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index 0d308cb6af969..228f967caf2f1 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -89,13 +89,21 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { } // namespace targets } // namespace clang -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}, +static constexpr int NumBuiltins = + clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsAMDGPU.def" -}; + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsAMDGPU.def" +}); const char *const AMDGPUTargetInfo::GCCRegNames[] = { "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", @@ -267,9 +275,9 @@ void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { !isAMDGCN(getTriple())); } -ArrayRef AMDGPUTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +AMDGPUTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts, diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h index ea4189cdea47d..3d6778fb5a76f 100644 --- a/clang/lib/Basic/Targets/AMDGPU.h +++ b/clang/lib/Basic/Targets/AMDGPU.h @@ -257,7 +257,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { StringRef CPU, const std::vector &FeatureVec) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool useFP16ConversionIntrinsics() const override { return false; } diff --git a/clang/lib/Basic/Targets/ARC.h b/clang/lib/Basic/Targets/ARC.h index 7f3d0aa15ab81..2b69f95591fa1 100644 --- a/clang/lib/Basic/Targets/ARC.h +++ b/clang/lib/Basic/Targets/ARC.h @@ -40,7 +40,9 @@ class LLVM_LIBRARY_VISIBILITY ARCTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp index 5aa2baeb81b73..637ee1cb9cf60 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -1074,31 +1074,99 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, } } -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#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, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#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, FEATURE, HeaderDesc::HEADER, LANGS}, -#include "clang/Basic/BuiltinsARM.def" +static constexpr int NumBuiltins = ARM::LastTSBuiltin - Builtin::FirstTSBuiltin; +static constexpr int NumNeonBuiltins = + NEON::FirstFp16Builtin - Builtin::FirstTSBuiltin; +static constexpr int NumFp16Builtins = + NEON::FirstTSBuiltin - NEON::FirstFp16Builtin; +static constexpr int NumMVEBuiltins = + ARM::FirstCDEBuiltin - NEON::FirstTSBuiltin; +static constexpr int NumCDEBuiltins = + ARM::FirstARMBuiltin - ARM::FirstCDEBuiltin; +static constexpr int NumARMBuiltins = ARM::LastTSBuiltin - ARM::FirstARMBuiltin; +static_assert(NumBuiltins == + (NumNeonBuiltins + NumFp16Builtins + NumMVEBuiltins + + NumCDEBuiltins + NumARMBuiltins)); + +namespace clang { +namespace NEON { +#define GET_NEON_BUILTIN_STR_TABLE +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_NEON_BUILTIN_INFOS +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_BUILTIN_INFOS +}; + +namespace FP16 { +#define GET_NEON_BUILTIN_STR_TABLE +#include "clang/Basic/arm_fp16.inc" +#undef GET_NEON_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_NEON_BUILTIN_INFOS +#include "clang/Basic/arm_fp16.inc" +#undef GET_NEON_BUILTIN_INFOS +}; +} // namespace FP16 +} // namespace NEON +} // namespace clang + +namespace { +namespace MVE { +#define GET_MVE_BUILTIN_STR_TABLE +#include "clang/Basic/arm_mve_builtins.inc" +#undef GET_MVE_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_MVE_BUILTIN_INFOS +#include "clang/Basic/arm_mve_builtins.inc" +#undef GET_MVE_BUILTIN_INFOS }; +} // namespace MVE -ArrayRef ARMTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin); +namespace CDE { +#define GET_CDE_BUILTIN_STR_TABLE +#include "clang/Basic/arm_cde_builtins.inc" +#undef GET_CDE_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_CDE_BUILTIN_INFOS +#include "clang/Basic/arm_cde_builtins.inc" +#undef GET_CDE_BUILTIN_INFOS +}; +} // namespace CDE +} // namespace + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsARM.def" + ; // namespace clang + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsARM.def" +}); + +llvm::SmallVector +ARMTargetInfo::getTargetBuiltins() const { + return { + {&NEON::BuiltinStrings, NEON::BuiltinInfos, "__builtin_neon_"}, + {&NEON::FP16::BuiltinStrings, NEON::FP16::BuiltinInfos, + "__builtin_neon_"}, + {&MVE::BuiltinStrings, MVE::BuiltinInfos, "__builtin_arm_mve_"}, + {&CDE::BuiltinStrings, CDE::BuiltinInfos, "__builtin_arm_cde_"}, + {&BuiltinStrings, BuiltinInfos}, + }; } bool ARMTargetInfo::isCLZForZeroUndef() const { return false; } diff --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h index 5f4acce7af5a4..22033a6da3389 100644 --- a/clang/lib/Basic/Targets/ARM.h +++ b/clang/lib/Basic/Targets/ARM.h @@ -196,7 +196,7 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool isCLZForZeroUndef() const override; BuiltinVaListKind getBuiltinVaListKind() const override; diff --git a/clang/lib/Basic/Targets/AVR.h b/clang/lib/Basic/Targets/AVR.h index df1f8d171efba..2117ab58e6f30 100644 --- a/clang/lib/Basic/Targets/AVR.h +++ b/clang/lib/Basic/Targets/AVR.h @@ -63,7 +63,9 @@ class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } bool allowsLargerPreferedTypeAlignment() const override { return false; } diff --git a/clang/lib/Basic/Targets/BPF.cpp b/clang/lib/Basic/Targets/BPF.cpp index f4684765b7ffb..a463de0884020 100644 --- a/clang/lib/Basic/Targets/BPF.cpp +++ b/clang/lib/Basic/Targets/BPF.cpp @@ -19,11 +19,19 @@ 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}, +static constexpr int NumBuiltins = + clang::BPF::LastTSBuiltin - Builtin::FirstTSBuiltin; + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsBPF.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS #include "clang/Basic/BuiltinsBPF.inc" +#undef GET_BUILTIN_INFOS }; +static_assert(std::size(BuiltinInfos) == NumBuiltins); void BPFTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -81,9 +89,9 @@ void BPFTargetInfo::fillValidCPUList(SmallVectorImpl &Values) const { Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); } -ArrayRef BPFTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::BPF::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +BPFTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } bool BPFTargetInfo::handleTargetFeatures(std::vector &Features, diff --git a/clang/lib/Basic/Targets/BPF.h b/clang/lib/Basic/Targets/BPF.h index 27a4b5f314970..d1f68b842348e 100644 --- a/clang/lib/Basic/Targets/BPF.h +++ b/clang/lib/Basic/Targets/BPF.h @@ -58,7 +58,7 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo { bool handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; std::string_view getClobbers() const override { return ""; } diff --git a/clang/lib/Basic/Targets/CSKY.cpp b/clang/lib/Basic/Targets/CSKY.cpp index c8bf8b9234d24..e698508a2370c 100644 --- a/clang/lib/Basic/Targets/CSKY.cpp +++ b/clang/lib/Basic/Targets/CSKY.cpp @@ -139,10 +139,6 @@ bool CSKYTargetInfo::handleTargetFeatures(std::vector &Features, return true; } -ArrayRef CSKYTargetInfo::getTargetBuiltins() const { - return ArrayRef(); -} - ArrayRef CSKYTargetInfo::getGCCRegNames() const { static const char *const GCCRegNames[] = { // Integer registers diff --git a/clang/lib/Basic/Targets/CSKY.h b/clang/lib/Basic/Targets/CSKY.h index 94d4eeb9a1fff..ddfbe4794daad 100644 --- a/clang/lib/Basic/Targets/CSKY.h +++ b/clang/lib/Basic/Targets/CSKY.h @@ -73,7 +73,9 @@ class LLVM_LIBRARY_VISIBILITY CSKYTargetInfo : public TargetInfo { unsigned getMinGlobalAlign(uint64_t, bool HasNonWeakDef) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } BuiltinVaListKind getBuiltinVaListKind() const override { return VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h index 4e6bc0e040398..6e3ddad626341 100644 --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -73,7 +73,9 @@ class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo { return Feature == "directx"; } - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } std::string_view getClobbers() const override { return ""; } diff --git a/clang/lib/Basic/Targets/Hexagon.cpp b/clang/lib/Basic/Targets/Hexagon.cpp index 2e173e01ed8ed..c19c2e76c511a 100644 --- a/clang/lib/Basic/Targets/Hexagon.cpp +++ b/clang/lib/Basic/Targets/Hexagon.cpp @@ -204,15 +204,26 @@ ArrayRef HexagonTargetInfo::getGCCRegAliases() const { return llvm::ArrayRef(GCCRegAliases); } -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, nullptr, HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::Hexagon::LastTSBuiltin - Builtin::FirstTSBuiltin; + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsHexagon.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsHexagon.inc" +#undef GET_BUILTIN_INFOS +}; + +static constexpr Builtin::Info PrefixedBuiltinInfos[] = { +#define GET_BUILTIN_PREFIXED_INFOS #include "clang/Basic/BuiltinsHexagon.inc" +#undef GET_BUILTIN_PREFIXED_INFOS }; +static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) == + NumBuiltins); bool HexagonTargetInfo::hasFeature(StringRef Feature) const { std::string VS = "hvxv" + HVXVersion; @@ -271,7 +282,8 @@ void HexagonTargetInfo::fillValidCPUList( Values.push_back(Suffix.Name); } -ArrayRef HexagonTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin - - Builtin::FirstTSBuiltin); +llvm::SmallVector +HexagonTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}, + {&BuiltinStrings, PrefixedBuiltinInfos, "__builtin_HEXAGON_"}}; } diff --git a/clang/lib/Basic/Targets/Hexagon.h b/clang/lib/Basic/Targets/Hexagon.h index 7f053ab7e4888..a65663ca09eee 100644 --- a/clang/lib/Basic/Targets/Hexagon.h +++ b/clang/lib/Basic/Targets/Hexagon.h @@ -66,7 +66,7 @@ class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo { BoolWidth = BoolAlign = 8; } - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override { diff --git a/clang/lib/Basic/Targets/Lanai.h b/clang/lib/Basic/Targets/Lanai.h index f7e439c7c9e1c..e32ef9d7d40da 100644 --- a/clang/lib/Basic/Targets/Lanai.h +++ b/clang/lib/Basic/Targets/Lanai.h @@ -78,7 +78,9 @@ class LLVM_LIBRARY_VISIBILITY LanaiTargetInfo : public TargetInfo { return TargetInfo::VoidPtrBuiltinVaList; } - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override { diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index bb0d0b68cfcb0..ca742797d7a3b 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -273,13 +273,55 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts, 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" -}; +static constexpr int NumBaseBuiltins = + LoongArch::FirstLSXBuiltin - Builtin::FirstTSBuiltin; +static constexpr int NumLSXBuiltins = + LoongArch::FirstLASXBuiltin - LoongArch::FirstLSXBuiltin; +static constexpr int NumLASXBuiltins = + LoongArch::LastTSBuiltin - LoongArch::FirstLASXBuiltin; +static constexpr int NumBuiltins = + LoongArch::LastTSBuiltin - Builtin::FirstTSBuiltin; +static_assert(NumBuiltins == + (NumBaseBuiltins + NumLSXBuiltins + NumLASXBuiltins)); + +static constexpr llvm::StringTable BuiltinBaseStrings = + CLANG_BUILTIN_STR_TABLE_START +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsLoongArchBase.def" +#undef TARGET_BUILTIN + ; + +static constexpr auto BuiltinBaseInfos = Builtin::MakeInfos({ +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsLoongArchBase.def" +#undef TARGET_BUILTIN +}); + +static constexpr llvm::StringTable BuiltinLSXStrings = + CLANG_BUILTIN_STR_TABLE_START +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsLoongArchLSX.def" +#undef TARGET_BUILTIN + ; + +static constexpr auto BuiltinLSXInfos = Builtin::MakeInfos({ +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsLoongArchLSX.def" +#undef TARGET_BUILTIN +}); + +static constexpr llvm::StringTable BuiltinLASXStrings = + CLANG_BUILTIN_STR_TABLE_START +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsLoongArchLASX.def" +#undef TARGET_BUILTIN + ; + +static constexpr auto BuiltinLASXInfos = Builtin::MakeInfos({ +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsLoongArchLASX.def" +#undef TARGET_BUILTIN +}); bool LoongArchTargetInfo::initFeatureMap( llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, @@ -306,9 +348,13 @@ bool LoongArchTargetInfo::hasFeature(StringRef Feature) const { .Default(false); } -ArrayRef LoongArchTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, clang::LoongArch::LastTSBuiltin - - Builtin::FirstTSBuiltin); +llvm::SmallVector +LoongArchTargetInfo::getTargetBuiltins() const { + return { + {&BuiltinBaseStrings, BuiltinBaseInfos}, + {&BuiltinLSXStrings, BuiltinLSXInfos}, + {&BuiltinLASXStrings, BuiltinLASXInfos}, + }; } bool LoongArchTargetInfo::handleTargetFeatures( diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index 5c34c84ff8d3e..4c7b53abfef9b 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -72,7 +72,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/M68k.cpp b/clang/lib/Basic/Targets/M68k.cpp index b5b29fd867563..e5b7f06829cd9 100644 --- a/clang/lib/Basic/Targets/M68k.cpp +++ b/clang/lib/Basic/Targets/M68k.cpp @@ -115,7 +115,8 @@ void M68kTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__HAVE_68881__"); } -ArrayRef M68kTargetInfo::getTargetBuiltins() const { +llvm::SmallVector +M68kTargetInfo::getTargetBuiltins() const { // FIXME: Implement. return {}; } diff --git a/clang/lib/Basic/Targets/M68k.h b/clang/lib/Basic/Targets/M68k.h index b732add77e034..729d79ff77fbf 100644 --- a/clang/lib/Basic/Targets/M68k.h +++ b/clang/lib/Basic/Targets/M68k.h @@ -44,7 +44,7 @@ class LLVM_LIBRARY_VISIBILITY M68kTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool hasFeature(StringRef Feature) const override; ArrayRef getGCCRegNames() const override; ArrayRef getGCCRegAliases() const override; diff --git a/clang/lib/Basic/Targets/MSP430.h b/clang/lib/Basic/Targets/MSP430.h index 2266ada25c1dd..d7d05f992f4f6 100644 --- a/clang/lib/Basic/Targets/MSP430.h +++ b/clang/lib/Basic/Targets/MSP430.h @@ -50,7 +50,7 @@ class LLVM_LIBRARY_VISIBILITY MSP430TargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override { + llvm::SmallVector getTargetBuiltins() const override { // FIXME: Implement. return {}; } diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp index d56995e3ccc48..866be53c8a363 100644 --- a/clang/lib/Basic/Targets/Mips.cpp +++ b/clang/lib/Basic/Targets/Mips.cpp @@ -20,13 +20,20 @@ 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}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsMips.def" + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY #include "clang/Basic/BuiltinsMips.def" -}; +}); bool MipsTargetInfo::processorSupportsGPR64() const { return llvm::StringSwitch(CPU) @@ -223,9 +230,9 @@ bool MipsTargetInfo::hasFeature(StringRef Feature) const { .Default(false); } -ArrayRef MipsTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +MipsTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } unsigned MipsTargetInfo::getUnwindWordWidth() const { diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index 7ddcd57053cb2..35501ed44ccd7 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -198,7 +198,7 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool hasFeature(StringRef Feature) const override; diff --git a/clang/lib/Basic/Targets/NVPTX.cpp b/clang/lib/Basic/Targets/NVPTX.cpp index a03f4983b9d03..1fbb7bbe33769 100644 --- a/clang/lib/Basic/Targets/NVPTX.cpp +++ b/clang/lib/Basic/Targets/NVPTX.cpp @@ -20,11 +20,19 @@ using namespace clang; using namespace clang::targets; -static constexpr Builtin::Info BuiltinInfo[] = { -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin; + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsNVPTX.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS #include "clang/Basic/BuiltinsNVPTX.inc" +#undef GET_BUILTIN_INFOS }; +static_assert(std::size(BuiltinInfos) == NumBuiltins); const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"}; @@ -294,7 +302,7 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, } } -ArrayRef NVPTXTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +NVPTXTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h index c6531148fe30c..6a868c42e1265 100644 --- a/clang/lib/Basic/Targets/NVPTX.h +++ b/clang/lib/Basic/Targets/NVPTX.h @@ -75,7 +75,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool useFP16ConversionIntrinsics() const override { return false; } diff --git a/clang/lib/Basic/Targets/PNaCl.h b/clang/lib/Basic/Targets/PNaCl.h index 7e0e10aa362d8..d162776b5a0d6 100644 --- a/clang/lib/Basic/Targets/PNaCl.h +++ b/clang/lib/Basic/Targets/PNaCl.h @@ -52,7 +52,9 @@ class LLVM_LIBRARY_VISIBILITY PNaClTargetInfo : public TargetInfo { return Feature == "pnacl"; } - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::PNaClABIBuiltinVaList; diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 1448069173b5f..2d8891a739ca3 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -19,15 +19,22 @@ 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}, -#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, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsPPC.def" -}; + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY +#include "clang/Basic/BuiltinsPPC.def" +}); /// handleTargetFeatures - Perform initialization based on the user /// configured set of features. @@ -927,9 +934,9 @@ void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { MaxAtomicInlineWidth = 128; } -ArrayRef PPCTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +PPCTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 3cd0fcad17293..db6ac6f0bd338 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -187,7 +187,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { StringRef getABI() const override { return ABI; } - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool isCLZForZeroUndef() const override { return false; } diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 61b8ae9d098ab..b4aa3206fcfab 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -240,22 +240,61 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, } } -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, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#include "clang/Basic/BuiltinsRISCV.inc" +static constexpr int NumRVVBuiltins = + RISCVVector::FirstSiFiveBuiltin - Builtin::FirstTSBuiltin; +static constexpr int NumRVVSiFiveBuiltins = + RISCVVector::FirstTSBuiltin - RISCVVector::FirstSiFiveBuiltin; +static constexpr int NumRISCVBuiltins = + RISCV::LastTSBuiltin - RISCVVector::FirstTSBuiltin; +static constexpr int NumBuiltins = + RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin; +static_assert(NumBuiltins == + (NumRVVBuiltins + NumRVVSiFiveBuiltins + NumRISCVBuiltins)); + +namespace RVV { +#define GET_RISCVV_BUILTIN_STR_TABLE +#include "clang/Basic/riscv_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_STR_TABLE +static_assert(BuiltinStrings.size() < 100'000); + +static constexpr std::array BuiltinInfos = { +#define GET_RISCVV_BUILTIN_INFOS +#include "clang/Basic/riscv_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_INFOS +}; +} // namespace RVV + +namespace RVVSiFive { +#define GET_RISCVV_BUILTIN_STR_TABLE +#include "clang/Basic/riscv_sifive_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = + { +#define GET_RISCVV_BUILTIN_INFOS +#include "clang/Basic/riscv_sifive_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_INFOS }; +} // namespace RVVSiFive + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsRISCV.inc" +#undef GET_BUILTIN_STR_TABLE -ArrayRef RISCVTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin); +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsRISCV.inc" +#undef GET_BUILTIN_INFOS +}; +static_assert(std::size(BuiltinInfos) == NumRISCVBuiltins); + +llvm::SmallVector +RISCVTargetInfo::getTargetBuiltins() const { + return { + {&RVV::BuiltinStrings, RVV::BuiltinInfos, "__builtin_rvv_"}, + {&RVVSiFive::BuiltinStrings, RVVSiFive::BuiltinInfos, "__builtin_rvv_"}, + {&BuiltinStrings, BuiltinInfos}, + }; } bool RISCVTargetInfo::initFeatureMap( diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h index d31c46f2bb16c..c26aa19080162 100644 --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -62,7 +62,7 @@ class RISCVTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/SPIR.cpp b/clang/lib/Basic/Targets/SPIR.cpp index f242fedc1ad66..5c076f694dfa4 100644 --- a/clang/lib/Basic/Targets/SPIR.cpp +++ b/clang/lib/Basic/Targets/SPIR.cpp @@ -20,15 +20,23 @@ 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}, +static constexpr int NumBuiltins = + clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin; + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsSPIRV.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS #include "clang/Basic/BuiltinsSPIRV.inc" +#undef GET_BUILTIN_INFOS }; +static_assert(std::size(BuiltinInfos) == NumBuiltins); -ArrayRef SPIRVTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +SPIRVTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } void SPIRTargetInfo::getTargetDefines(const LangOptions &Opts, @@ -94,7 +102,8 @@ SPIRV64AMDGCNTargetInfo::convertConstraint(const char *&Constraint) const { return AMDGPUTI.convertConstraint(Constraint); } -ArrayRef SPIRV64AMDGCNTargetInfo::getTargetBuiltins() const { +llvm::SmallVector +SPIRV64AMDGCNTargetInfo::getTargetBuiltins() const { return AMDGPUTI.getTargetBuiltins(); } diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index c0849b69dcdb3..61f9ef7e3e361 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -161,7 +161,9 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo { // memcpy as per section 3 of the SPIR spec. bool useFP16ConversionIntrinsics() const override { return false; } - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } std::string_view getClobbers() const override { return ""; } @@ -315,7 +317,9 @@ class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo { resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-" "v256:256-v512:512-v1024:1024-n8:16:32:64-G1"); } - ArrayRef getTargetBuiltins() const override; + + llvm::SmallVector getTargetBuiltins() const override; + void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; }; @@ -410,7 +414,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final std::string convertConstraint(const char *&Constraint) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; diff --git a/clang/lib/Basic/Targets/Sparc.h b/clang/lib/Basic/Targets/Sparc.h index 9c529a5bc5e7f..3215e648ba6c3 100644 --- a/clang/lib/Basic/Targets/Sparc.h +++ b/clang/lib/Basic/Targets/Sparc.h @@ -48,7 +48,7 @@ class LLVM_LIBRARY_VISIBILITY SparcTargetInfo : public TargetInfo { bool hasFeature(StringRef Feature) const override; - ArrayRef getTargetBuiltins() const override { + llvm::SmallVector getTargetBuiltins() const override { // FIXME: Implement! return {}; } diff --git a/clang/lib/Basic/Targets/SystemZ.cpp b/clang/lib/Basic/Targets/SystemZ.cpp index c836d110d26d5..0e9a61c6a01c8 100644 --- a/clang/lib/Basic/Targets/SystemZ.cpp +++ b/clang/lib/Basic/Targets/SystemZ.cpp @@ -20,13 +20,21 @@ 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}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::SystemZ::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsSystemZ.def" -}; + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsSystemZ.def" +}); const char *const SystemZTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -172,7 +180,7 @@ void SystemZTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__VEC__", "10305"); } -ArrayRef SystemZTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, clang::SystemZ::LastTSBuiltin - - Builtin::FirstTSBuiltin); +llvm::SmallVector +SystemZTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index bd2827cf13a5b..4ca3f53f83cba 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -100,7 +100,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; ArrayRef getGCCRegNames() const override; diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h index edec30bf69de0..46c70de8f9ec1 100644 --- a/clang/lib/Basic/Targets/TCE.h +++ b/clang/lib/Basic/Targets/TCE.h @@ -96,7 +96,9 @@ class LLVM_LIBRARY_VISIBILITY TCETargetInfo : public TargetInfo { bool hasFeature(StringRef Feature) const override { return Feature == "tce"; } - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } std::string_view getClobbers() const override { return ""; } diff --git a/clang/lib/Basic/Targets/VE.cpp b/clang/lib/Basic/Targets/VE.cpp index 67cae8faf6052..5451f3c303637 100644 --- a/clang/lib/Basic/Targets/VE.cpp +++ b/clang/lib/Basic/Targets/VE.cpp @@ -18,11 +18,19 @@ 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}, +static constexpr int NumBuiltins = + clang::VE::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsVE.def" + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY #include "clang/Basic/BuiltinsVE.def" -}; +}); void VETargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -39,7 +47,6 @@ void VETargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); } -ArrayRef VETargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::VE::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector VETargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } diff --git a/clang/lib/Basic/Targets/VE.h b/clang/lib/Basic/Targets/VE.h index 7e8fdf6096ef2..e9b7e92f3f850 100644 --- a/clang/lib/Basic/Targets/VE.h +++ b/clang/lib/Basic/Targets/VE.h @@ -55,7 +55,7 @@ class LLVM_LIBRARY_VISIBILITY VETargetInfo : public TargetInfo { bool hasSjLjLowering() const override { return true; } - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp index 7b0fd0c841ba2..f19c57f1a3a50 100644 --- a/clang/lib/Basic/Targets/WebAssembly.cpp +++ b/clang/lib/Basic/Targets/WebAssembly.cpp @@ -20,15 +20,22 @@ 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}, -#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, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::WebAssembly::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsWebAssembly.def" + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY #include "clang/Basic/BuiltinsWebAssembly.def" -}; +}); static constexpr llvm::StringLiteral ValidCPUNames[] = { {"mvp"}, {"bleeding-edge"}, {"generic"}, {"lime1"}}; @@ -360,9 +367,9 @@ bool WebAssemblyTargetInfo::handleTargetFeatures( return true; } -ArrayRef WebAssemblyTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin - - Builtin::FirstTSBuiltin); +llvm::SmallVector +WebAssemblyTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } void WebAssemblyTargetInfo::adjust(DiagnosticsEngine &Diags, diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index cfecc59ac75fd..fb48c786a7edb 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -121,7 +121,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo { bool setCPU(const std::string &Name) final { return isValidCPUName(Name); } - ArrayRef getTargetBuiltins() const final; + llvm::SmallVector getTargetBuiltins() const final; BuiltinVaListKind getBuiltinVaListKind() const final { return VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index 40ad8fd9a0967..84a05cec04e7f 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -23,23 +23,53 @@ namespace clang { namespace targets { -static constexpr Builtin::Info BuiltinInfoX86[] = { -#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}, -#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, +// The x86-32 builtins are a subset and prefix of the x86-64 builtins. +static constexpr int NumX86Builtins = + X86::LastX86CommonBuiltin - Builtin::FirstTSBuiltin + 1; +static constexpr int NumX86_64Builtins = + X86::LastTSBuiltin - X86::FirstX86_64Builtin; +static constexpr int NumBuiltins = X86::LastTSBuiltin - Builtin::FirstTSBuiltin; +static_assert(NumBuiltins == (NumX86Builtins + NumX86_64Builtins)); + +namespace X86 { +#define GET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsX86.inc" +#undef GET_BUILTIN_STR_TABLE -#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}, -#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsX86.inc" +#undef GET_BUILTIN_INFOS +}; + +static constexpr Builtin::Info PrefixedBuiltinInfos[] = { +#define GET_BUILTIN_PREFIXED_INFOS +#include "clang/Basic/BuiltinsX86.inc" +#undef GET_BUILTIN_PREFIXED_INFOS +}; +static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) == + NumX86Builtins); +} // namespace X86 + +namespace X86_64 { +#define GET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsX86_64.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsX86_64.inc" +#undef GET_BUILTIN_INFOS +}; + +static constexpr Builtin::Info PrefixedBuiltinInfos[] = { +#define GET_BUILTIN_PREFIXED_INFOS +#include "clang/Basic/BuiltinsX86_64.inc" +#undef GET_BUILTIN_PREFIXED_INFOS }; +static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) == + NumX86_64Builtins); +} // namespace X86_64 static const char *const GCCRegNames[] = { "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", @@ -1856,12 +1886,21 @@ ArrayRef X86TargetInfo::getGCCAddlRegNames() const { return llvm::ArrayRef(AddlRegNames); } -ArrayRef X86_32TargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin - - Builtin::FirstTSBuiltin + 1); +llvm::SmallVector +X86_32TargetInfo::getTargetBuiltins() const { + return { + {&X86::BuiltinStrings, X86::BuiltinInfos}, + {&X86::BuiltinStrings, X86::PrefixedBuiltinInfos, "__builtin_ia32_"}, + }; } -ArrayRef X86_64TargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfoX86, - X86::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +X86_64TargetInfo::getTargetBuiltins() const { + return { + {&X86::BuiltinStrings, X86::BuiltinInfos}, + {&X86::BuiltinStrings, X86::PrefixedBuiltinInfos, "__builtin_ia32_"}, + {&X86_64::BuiltinStrings, X86_64::BuiltinInfos}, + {&X86_64::BuiltinStrings, X86_64::PrefixedBuiltinInfos, + "__builtin_ia32_"}, + }; } diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 8bd54e362526f..205edcab9ccb3 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -509,7 +509,7 @@ class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo { MaxAtomicInlineWidth = 64; } - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool hasBitIntType() const override { return true; } size_t getMaxBitIntWidth() const override { @@ -821,7 +821,7 @@ class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo { MaxAtomicInlineWidth = 128; } - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool hasBitIntType() const override { return true; } size_t getMaxBitIntWidth() const override { diff --git a/clang/lib/Basic/Targets/XCore.cpp b/clang/lib/Basic/Targets/XCore.cpp index fd377bbfb90e1..c725703ede5b0 100644 --- a/clang/lib/Basic/Targets/XCore.cpp +++ b/clang/lib/Basic/Targets/XCore.cpp @@ -18,13 +18,20 @@ 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}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + XCore::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsXCore.def" + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY #include "clang/Basic/BuiltinsXCore.def" -}; +}); void XCoreTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -32,7 +39,7 @@ void XCoreTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__XS1B__"); } -ArrayRef XCoreTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::XCore::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +XCoreTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } diff --git a/clang/lib/Basic/Targets/XCore.h b/clang/lib/Basic/Targets/XCore.h index 84fd59d1a71e4..9af9e0658f629 100644 --- a/clang/lib/Basic/Targets/XCore.h +++ b/clang/lib/Basic/Targets/XCore.h @@ -43,7 +43,7 @@ class LLVM_LIBRARY_VISIBILITY XCoreTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/Xtensa.h b/clang/lib/Basic/Targets/Xtensa.h index a440ba8aa3c6d..470835aacff52 100644 --- a/clang/lib/Basic/Targets/Xtensa.h +++ b/clang/lib/Basic/Targets/Xtensa.h @@ -56,8 +56,8 @@ class LLVM_LIBRARY_VISIBILITY XtensaTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override { - return std::nullopt; + llvm::SmallVector getTargetBuiltins() const override { + return {}; } BuiltinVaListKind getBuiltinVaListKind() const override { diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 4d3d9e9897c14..96e1e0dc11181 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -265,8 +265,10 @@ llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, unsigned BuiltinID) { assert(Context.BuiltinInfo.isLibFunction(BuiltinID)); - // Get the name, skip over the __builtin_ prefix (if necessary). - StringRef Name; + // Get the name, skip over the __builtin_ prefix (if necessary). We may have + // to build this up so provide a small stack buffer to handle the vast + // majority of names. + llvm::SmallString<64> Name; GlobalDecl D(FD); // TODO: This list should be expanded or refactored after all GCC-compatible @@ -6574,7 +6576,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, LargestVectorWidth = std::max(LargestVectorWidth, VectorWidth); // See if we have a target specific intrinsic. - StringRef Name = getContext().BuiltinInfo.getName(BuiltinID); + std::string Name = getContext().BuiltinInfo.getName(BuiltinID); Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; StringRef Prefix = llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch()); @@ -21580,7 +21582,7 @@ static Value *MakeHalfType(unsigned IntrinsicID, unsigned BuiltinID, auto &C = CGF.CGM.getContext(); if (!(C.getLangOpts().NativeHalfType || !C.getTargetInfo().useFP16ConversionIntrinsics())) { - CGF.CGM.Error(E->getExprLoc(), C.BuiltinInfo.getName(BuiltinID).str() + + CGF.CGM.Error(E->getExprLoc(), C.BuiltinInfo.getQuotedName(BuiltinID) + " requires native half type support."); return nullptr; } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 82002b8d8e4d4..02615bb13dfb8 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4015,7 +4015,8 @@ namespace { unsigned BuiltinID = FD->getBuiltinID(); if (!BuiltinID || !BI.isLibFunction(BuiltinID)) return false; - StringRef BuiltinName = BI.getName(BuiltinID); + std::string BuiltinNameStr = BI.getName(BuiltinID); + StringRef BuiltinName = BuiltinNameStr; if (BuiltinName.starts_with("__builtin_") && Name == BuiltinName.slice(strlen("__builtin_"), StringRef::npos)) { return true; diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp index 71dfe68f104ed..b4b40f293b28e 100644 --- a/clang/lib/Sema/SemaARM.cpp +++ b/clang/lib/Sema/SemaARM.cpp @@ -709,22 +709,18 @@ bool SemaARM::CheckNeonBuiltinFunctionCall(const TargetInfo &TI, CallExpr *TheCall) { if (const FunctionDecl *FD = SemaRef.getCurFunctionDecl(/*AllowLambda=*/true)) { + std::optional BuiltinType; switch (BuiltinID) { default: break; -#define GET_NEON_BUILTINS -#define TARGET_BUILTIN(id, ...) case NEON::BI##id: -#define BUILTIN(id, ...) case NEON::BI##id: +#define GET_NEON_STREAMING_COMPAT_FLAG #include "clang/Basic/arm_neon.inc" - if (checkArmStreamingBuiltin(SemaRef, TheCall, FD, ArmNonStreaming, - BuiltinID)) - return true; - break; -#undef TARGET_BUILTIN -#undef BUILTIN -#undef GET_NEON_BUILTINS +#undef GET_NEON_STREAMING_COMPAT_FLAG } + if (BuiltinType && + checkArmStreamingBuiltin(SemaRef, TheCall, FD, *BuiltinType, BuiltinID)) + return true; } llvm::APSInt Result; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 61b2c8cf1cad7..66c233de4ef30 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1236,7 +1236,9 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, bool IsChkVariant = false; auto GetFunctionName = [&]() { - StringRef FunctionName = getASTContext().BuiltinInfo.getName(BuiltinID); + std::string FunctionNameStr = + getASTContext().BuiltinInfo.getName(BuiltinID); + llvm::StringRef FunctionName = FunctionNameStr; // Skim off the details of whichever builtin was called to produce a better // diagnostic, as it's unlikely that the user wrote the __builtin // explicitly. @@ -1246,7 +1248,7 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, } else { FunctionName.consume_front("__builtin_"); } - return FunctionName; + return FunctionName.str(); }; switch (BuiltinID) { @@ -1290,7 +1292,7 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, unsigned SourceSize) { DiagID = diag::warn_fortify_scanf_overflow; unsigned Index = ArgIndex + DataIndex; - StringRef FunctionName = GetFunctionName(); + std::string FunctionName = GetFunctionName(); DiagRuntimeBehavior(TheCall->getArg(Index)->getBeginLoc(), TheCall, PDiag(DiagID) << FunctionName << (Index + 1) << DestSize << SourceSize); @@ -1439,7 +1441,7 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0) return; - StringRef FunctionName = GetFunctionName(); + std::string FunctionName = GetFunctionName(); SmallString<16> DestinationStr; SmallString<16> SourceStr; @@ -2449,7 +2451,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc()); break; } -#define BUILTIN(ID, TYPE, ATTRS) #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ case Builtin::BI##ID: \ return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID); @@ -4584,7 +4585,7 @@ ExprResult Sema::BuiltinAtomicOverloaded(ExprResult TheCallResult) { // Get the decl for the concrete builtin from this, we can tell what the // concrete integer type we should convert to is. unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex]; - StringRef NewBuiltinName = Context.BuiltinInfo.getName(NewBuiltinID); + std::string NewBuiltinName = Context.BuiltinInfo.getName(NewBuiltinID); FunctionDecl *NewBuiltinDecl; if (NewBuiltinID == BuiltinID) NewBuiltinDecl = FDecl; @@ -8379,7 +8380,7 @@ static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType) { bool EmitHeaderHint = true; const char *HeaderName = nullptr; - StringRef FunctionName; + std::string FunctionName; if (S.getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) { FunctionName = "std::abs"; if (ArgType->isIntegralOrEnumerationType()) { @@ -8545,7 +8546,7 @@ void Sema::CheckAbsoluteValueFunction(const CallExpr *Call, // Unsigned types cannot be negative. Suggest removing the absolute value // function call. if (ArgType->isUnsignedIntegerType()) { - StringRef FunctionName = + std::string FunctionName = IsStdAbs ? "std::abs" : Context.BuiltinInfo.getName(AbsKind); Diag(Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType; Diag(Call->getExprLoc(), diag::note_remove_abs) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ba4aaa94b90ff..3cd4010740d19 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6695,7 +6695,7 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, Expr *Sema::BuildBuiltinCallExpr(SourceLocation Loc, Builtin::ID Id, MultiExprArg CallArgs) { - StringRef Name = Context.BuiltinInfo.getName(Id); + std::string Name = Context.BuiltinInfo.getName(Id); LookupResult R(*this, &Context.Idents.get(Name), Loc, Sema::LookupOrdinaryName); LookupName(R, TUScope, /*AllowBuiltinCreation=*/true); diff --git a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp index 96464b30c078f..d0145293fa3e5 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp @@ -55,7 +55,7 @@ bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD, if (BId != 0) { if (Name.empty()) return true; - StringRef BName = FD->getASTContext().BuiltinInfo.getName(BId); + std::string BName = FD->getASTContext().BuiltinInfo.getName(BId); size_t start = BName.find(Name); if (start != StringRef::npos) { // Accept exact match. diff --git a/clang/test/TableGen/target-builtins-prototype-parser.td b/clang/test/TableGen/target-builtins-prototype-parser.td index a753f906a674f..451f1a18b8ad0 100644 --- a/clang/test/TableGen/target-builtins-prototype-parser.td +++ b/clang/test/TableGen/target-builtins-prototype-parser.td @@ -10,55 +10,55 @@ include "clang/Basic/BuiltinsBase.td" def : Builtin { -// CHECK: BUILTIN(__builtin_01, "E8idE4b", "") +// CHECK: Builtin::Info{{.*}} __builtin_01 {{.*}} /* E8idE4b */ let Prototype = "_ExtVector<8,int>(double, _ExtVector<4, bool>)"; let Spellings = ["__builtin_01"]; } def : Builtin { -// CHECK: BUILTIN(__builtin_02, "E8UiE4s", "") +// CHECK: Builtin::Info{{.*}} __builtin_02 {{.*}} /* E8UiE4s */ let Prototype = "_ExtVector<8,unsigned int>(_ExtVector<4, short>)"; let Spellings = ["__builtin_02"]; } def : Builtin { -// CHECK: BUILTIN(__builtin_03, "di", "") +// CHECK: Builtin::Info{{.*}} __builtin_03 {{.*}} /* di */ let Prototype = "double(int)"; let Spellings = ["__builtin_03"]; } def : Builtin { -// CHECK: BUILTIN(__builtin_04, "diIUi", "") +// CHECK: Builtin::Info{{.*}} __builtin_04 {{.*}} /* diIUi */ let Prototype = "double(int, _Constant unsigned int)"; let Spellings = ["__builtin_04"]; } def : Builtin { -// CHECK: BUILTIN(__builtin_05, "v&v&", "") +// CHECK: Builtin::Info{{.*}} __builtin_05 {{.*}} /* v&v& */ let Prototype = "void&(void&)"; let Spellings = ["__builtin_05"]; } def : Builtin { -// CHECK: BUILTIN(__builtin_06, "v*v*cC*.", "") +// CHECK: Builtin::Info{{.*}} __builtin_06 {{.*}} /* v*v*cC*. */ let Prototype = "void*(void*, char const*, ...)"; let Spellings = ["__builtin_06"]; } def : Builtin { -// CHECK: BUILTIN(__builtin_07, "E8iE4dE4b.", "") +// CHECK: Builtin::Info{{.*}} __builtin_07 {{.*}} /* E8iE4dE4b. */ let Prototype = "_ExtVector<8, int>(_ExtVector<4,double>, _ExtVector<4, bool>, ...)"; let Spellings = ["__builtin_07"]; } def : Builtin { -// CHECK: BUILTIN(__builtin_08, "di*R", "") +// CHECK: Builtin::Info{{.*}} __builtin_08 {{.*}} /* di*R */ let Prototype = "double(int * restrict)"; let Spellings = ["__builtin_08"]; } def : Builtin { -// CHECK: BUILTIN(__builtin_09, "V2yy", "") +// CHECK: Builtin::Info{{.*}} __builtin_09 {{.*}} /* V2yy */ let Prototype = "_Vector<2, __bf16>(__bf16)"; let Spellings = ["__builtin_09"]; } diff --git a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp index 5c5f011cd940e..352765acf5338 100644 --- a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp +++ b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp @@ -15,7 +15,9 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringToOffsetTable.h" #include "llvm/TableGen/TableGenBackend.h" +#include using namespace llvm; @@ -29,6 +31,125 @@ enum class BuiltinType { TargetLibBuiltin, }; +class HeaderNameParser { +public: + HeaderNameParser(const Record *Builtin) { + for (char c : Builtin->getValueAsString("Header")) { + if (std::islower(c)) + HeaderName += static_cast(std::toupper(c)); + else if (c == '.' || c == '_' || c == '/' || c == '-') + HeaderName += '_'; + else + PrintFatalError(Builtin->getLoc(), "Unexpected header name"); + } + } + + void Print(raw_ostream &OS) const { OS << HeaderName; } + +private: + std::string HeaderName; +}; + +struct Builtin { + BuiltinType BT; + std::string Name; + std::string Type; + std::string Attributes; + + const Record *BuiltinRecord; + + void EmitEnumerator(llvm::raw_ostream &OS) const { + OS << " BI"; + // If there is a required name prefix, include its spelling in the + // enumerator. + if (auto *PrefixRecord = + BuiltinRecord->getValueAsOptionalDef("RequiredNamePrefix")) + OS << PrefixRecord->getValueAsString("Spelling"); + OS << Name << ",\n"; + } + + void EmitInfo(llvm::raw_ostream &OS, const StringToOffsetTable &Table) const { + OS << " Builtin::Info{Builtin::Info::StrOffsets{" + << Table.GetStringOffset(Name) << " /* " << Name << " */, " + << Table.GetStringOffset(Type) << " /* " << Type << " */, " + << Table.GetStringOffset(Attributes) << " /* " << Attributes << " */, "; + if (BT == BuiltinType::TargetBuiltin) { + const auto &Features = BuiltinRecord->getValueAsString("Features"); + OS << Table.GetStringOffset(Features) << " /* " << Features << " */"; + } else { + OS << "0"; + } + OS << "}, "; + if (BT == BuiltinType::LibBuiltin || BT == BuiltinType::TargetLibBuiltin) { + OS << "HeaderDesc::"; + HeaderNameParser{BuiltinRecord}.Print(OS); + } else { + OS << "HeaderDesc::NO_HEADER"; + } + OS << ", "; + if (BT == BuiltinType::LibBuiltin || BT == BuiltinType::LangBuiltin || + BT == BuiltinType::TargetLibBuiltin) { + OS << BuiltinRecord->getValueAsString("Languages"); + } else { + OS << "ALL_LANGUAGES"; + } + OS << "},\n"; + } + + void EmitXMacro(llvm::raw_ostream &OS) const { + if (BuiltinRecord->getValueAsBit("RequiresUndef")) + OS << "#undef " << Name << '\n'; + switch (BT) { + case BuiltinType::LibBuiltin: + OS << "LIBBUILTIN"; + break; + case BuiltinType::LangBuiltin: + OS << "LANGBUILTIN"; + break; + case BuiltinType::Builtin: + OS << "BUILTIN"; + break; + case BuiltinType::AtomicBuiltin: + OS << "ATOMIC_BUILTIN"; + break; + case BuiltinType::TargetBuiltin: + OS << "TARGET_BUILTIN"; + break; + case BuiltinType::TargetLibBuiltin: + OS << "TARGET_HEADER_BUILTIN"; + break; + } + + OS << "(" << Name << ", \"" << Type << "\", \"" << Attributes << "\""; + + switch (BT) { + case BuiltinType::LibBuiltin: { + OS << ", "; + HeaderNameParser{BuiltinRecord}.Print(OS); + [[fallthrough]]; + } + case BuiltinType::LangBuiltin: { + OS << ", " << BuiltinRecord->getValueAsString("Languages"); + break; + } + case BuiltinType::TargetLibBuiltin: { + OS << ", "; + HeaderNameParser{BuiltinRecord}.Print(OS); + OS << ", " << BuiltinRecord->getValueAsString("Languages"); + [[fallthrough]]; + } + case BuiltinType::TargetBuiltin: { + OS << ", \"" << BuiltinRecord->getValueAsString("Features") << "\""; + break; + } + case BuiltinType::AtomicBuiltin: + case BuiltinType::Builtin: + break; + } + OS << ")\n"; + } +}; + class PrototypeParser { public: PrototypeParser(StringRef Substitution, const Record *Builtin) @@ -37,6 +158,8 @@ class PrototypeParser { ParsePrototype(Builtin->getValueAsString("Prototype")); } + std::string takeTypeString() && { return std::move(Type); } + private: void ParsePrototype(StringRef Prototype) { Prototype = Prototype.trim(); @@ -243,37 +366,15 @@ class PrototypeParser { } } -public: - void Print(raw_ostream &OS) const { OS << ", \"" << Type << '\"'; } - -private: SMLoc Loc; StringRef Substitution; bool EnableOpenCLLong; std::string Type; }; -class HeaderNameParser { -public: - HeaderNameParser(const Record *Builtin) { - for (char c : Builtin->getValueAsString("Header")) { - if (std::islower(c)) - HeaderName += static_cast(std::toupper(c)); - else if (c == '.' || c == '_' || c == '/' || c == '-') - HeaderName += '_'; - else - PrintFatalError(Builtin->getLoc(), "Unexpected header name"); - } - } - - void Print(raw_ostream &OS) const { OS << HeaderName; } - -private: - std::string HeaderName; -}; - -void PrintAttributes(const Record *Builtin, BuiltinType BT, raw_ostream &OS) { - OS << '\"'; +std::string renderAttributes(const Record *Builtin, BuiltinType BT) { + std::string Attributes; + raw_string_ostream OS(Attributes); if (Builtin->isSubClassOf("LibBuiltin")) { if (BT == BuiltinType::LibBuiltin) { OS << 'f'; @@ -302,63 +403,18 @@ void PrintAttributes(const Record *Builtin, BuiltinType BT, raw_ostream &OS) { OS << '>'; } } - OS << '\"'; + return Attributes; } -void EmitBuiltinDef(raw_ostream &OS, StringRef Substitution, - const Record *Builtin, Twine Spelling, BuiltinType BT) { - if (Builtin->getValueAsBit("RequiresUndef")) - OS << "#undef " << Spelling << '\n'; - switch (BT) { - case BuiltinType::LibBuiltin: - OS << "LIBBUILTIN"; - break; - case BuiltinType::LangBuiltin: - OS << "LANGBUILTIN"; - break; - case BuiltinType::Builtin: - OS << "BUILTIN"; - break; - case BuiltinType::AtomicBuiltin: - OS << "ATOMIC_BUILTIN"; - break; - case BuiltinType::TargetBuiltin: - OS << "TARGET_BUILTIN"; - break; - case BuiltinType::TargetLibBuiltin: - OS << "TARGET_HEADER_BUILTIN"; - break; - } - - OS << "(" << Spelling; - PrototypeParser{Substitution, Builtin}.Print(OS); - OS << ", "; - PrintAttributes(Builtin, BT, OS); - - switch (BT) { - case BuiltinType::LibBuiltin: { - OS << ", "; - HeaderNameParser{Builtin}.Print(OS); - [[fallthrough]]; - } - case BuiltinType::LangBuiltin: { - OS << ", " << Builtin->getValueAsString("Languages"); - break; - } - case BuiltinType::TargetLibBuiltin: { - OS << ", "; - HeaderNameParser{Builtin}.Print(OS); - OS << ", " << Builtin->getValueAsString("Languages"); - [[fallthrough]]; - } - case BuiltinType::TargetBuiltin: - OS << ", \"" << Builtin->getValueAsString("Features") << "\""; - break; - case BuiltinType::AtomicBuiltin: - case BuiltinType::Builtin: - break; - } - OS << ")\n"; +Builtin buildBuiltin(StringRef Substitution, const Record *BuiltinRecord, + Twine Spelling, BuiltinType BT) { + Builtin B; + B.BT = BT; + B.Name = Spelling.str(); + B.Type = PrototypeParser(Substitution, BuiltinRecord).takeTypeString(); + B.Attributes = renderAttributes(BuiltinRecord, BT); + B.BuiltinRecord = BuiltinRecord; + return B; } struct TemplateInsts { @@ -384,10 +440,11 @@ TemplateInsts getTemplateInsts(const Record *R) { return temp; } -void EmitBuiltin(raw_ostream &OS, const Record *Builtin) { +void collectBuiltins(const Record *BuiltinRecord, + SmallVectorImpl &Builtins) { TemplateInsts Templates = {}; - if (Builtin->isSubClassOf("Template")) { - Templates = getTemplateInsts(Builtin); + if (BuiltinRecord->isSubClassOf("Template")) { + Templates = getTemplateInsts(BuiltinRecord); } else { Templates.Affix.emplace_back(); Templates.Substitution.emplace_back(); @@ -395,26 +452,28 @@ void EmitBuiltin(raw_ostream &OS, const Record *Builtin) { for (auto [Substitution, Affix] : zip(Templates.Substitution, Templates.Affix)) { - for (StringRef Spelling : Builtin->getValueAsListOfStrings("Spellings")) { + for (StringRef Spelling : + BuiltinRecord->getValueAsListOfStrings("Spellings")) { auto FullSpelling = (Templates.IsPrefix ? Affix + Spelling : Spelling + Affix).str(); BuiltinType BT = BuiltinType::Builtin; - if (Builtin->isSubClassOf("AtomicBuiltin")) { + if (BuiltinRecord->isSubClassOf("AtomicBuiltin")) { BT = BuiltinType::AtomicBuiltin; - } else if (Builtin->isSubClassOf("LangBuiltin")) { + } else if (BuiltinRecord->isSubClassOf("LangBuiltin")) { BT = BuiltinType::LangBuiltin; - } else if (Builtin->isSubClassOf("TargetLibBuiltin")) { + } else if (BuiltinRecord->isSubClassOf("TargetLibBuiltin")) { BT = BuiltinType::TargetLibBuiltin; - } else if (Builtin->isSubClassOf("TargetBuiltin")) { + } else if (BuiltinRecord->isSubClassOf("TargetBuiltin")) { BT = BuiltinType::TargetBuiltin; - } else if (Builtin->isSubClassOf("LibBuiltin")) { + } else if (BuiltinRecord->isSubClassOf("LibBuiltin")) { BT = BuiltinType::LibBuiltin; - if (Builtin->getValueAsBit("AddBuiltinPrefixedAlias")) - EmitBuiltinDef(OS, Substitution, Builtin, - std::string("__builtin_") + FullSpelling, - BuiltinType::Builtin); + if (BuiltinRecord->getValueAsBit("AddBuiltinPrefixedAlias")) + Builtins.push_back(buildBuiltin( + Substitution, BuiltinRecord, + std::string("__builtin_") + FullSpelling, BuiltinType::Builtin)); } - EmitBuiltinDef(OS, Substitution, Builtin, FullSpelling, BT); + Builtins.push_back( + buildBuiltin(Substitution, BuiltinRecord, FullSpelling, BT)); } } } @@ -423,47 +482,112 @@ void EmitBuiltin(raw_ostream &OS, const Record *Builtin) { void clang::EmitClangBuiltins(const RecordKeeper &Records, raw_ostream &OS) { emitSourceFileHeader("List of builtins that Clang recognizes", OS); - OS << R"c++( -#if defined(BUILTIN) && !defined(LIBBUILTIN) -# define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS) -#endif - -#if defined(BUILTIN) && !defined(LANGBUILTIN) -# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS) -#endif - -// Some of our atomics builtins are handled by AtomicExpr rather than -// as normal builtin CallExprs. This macro is used for such builtins. -#ifndef ATOMIC_BUILTIN -# define ATOMIC_BUILTIN(ID, TYPE, ATTRS) BUILTIN(ID, TYPE, ATTRS) -#endif - -#if defined(BUILTIN) && !defined(TARGET_BUILTIN) -# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) -#endif - -#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) -# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) -#endif -)c++"; + SmallVector Builtins; + // AtomicBuiltins are order dependent. Emit them first to make manual checking + // easier and so we can build a special atomic builtin X-macro. + for (const auto *BuiltinRecord : + Records.getAllDerivedDefinitions("AtomicBuiltin")) + collectBuiltins(BuiltinRecord, Builtins); + unsigned NumAtomicBuiltins = Builtins.size(); + + for (const auto *BuiltinRecord : + Records.getAllDerivedDefinitions("Builtin")) { + if (BuiltinRecord->isSubClassOf("AtomicBuiltin")) + continue; + // Prefixed builtins are also special and we emit them last so they can have + // their own representation that skips the prefix. + if (BuiltinRecord->getValueAsOptionalDef("RequiredNamePrefix")) + continue; - // AtomicBuiltins are order dependent - // emit them first to make manual checking easier - for (const auto *Builtin : Records.getAllDerivedDefinitions("AtomicBuiltin")) - EmitBuiltin(OS, Builtin); + collectBuiltins(BuiltinRecord, Builtins); + } - for (const auto *Builtin : Records.getAllDerivedDefinitions("Builtin")) { - if (Builtin->isSubClassOf("AtomicBuiltin")) + // Now collect (and count) the prefixed builtins. + unsigned NumPrefixedBuiltins = Builtins.size(); + const Record *FirstPrefix = nullptr; + for (const auto *BuiltinRecord : + Records.getAllDerivedDefinitions("Builtin")) { + auto *Prefix = BuiltinRecord->getValueAsOptionalDef("RequiredNamePrefix"); + if (!Prefix) continue; - EmitBuiltin(OS, Builtin); + + if (!FirstPrefix) + FirstPrefix = Prefix; + assert(Prefix == FirstPrefix && + "Multiple distinct prefixes which is not currently supported!"); + assert(!BuiltinRecord->isSubClassOf("AtomicBuiltin") && + "Cannot require a name prefix for an atomic builtin."); + collectBuiltins(BuiltinRecord, Builtins); } + NumPrefixedBuiltins = Builtins.size() - NumPrefixedBuiltins; + + auto AtomicBuiltins = ArrayRef(Builtins).slice(0, NumAtomicBuiltins); + auto UnprefixedBuiltins = ArrayRef(Builtins).drop_back(NumPrefixedBuiltins); + auto PrefixedBuiltins = ArrayRef(Builtins).take_back(NumPrefixedBuiltins); + + // Collect strings into a table. + StringToOffsetTable Table; + Table.GetOrAddStringOffset(""); + for (const auto &B : Builtins) { + Table.GetOrAddStringOffset(B.Name); + Table.GetOrAddStringOffset(B.Type); + Table.GetOrAddStringOffset(B.Attributes); + if (B.BT == BuiltinType::TargetBuiltin) + Table.GetOrAddStringOffset(B.BuiltinRecord->getValueAsString("Features")); + } + + // Emit enumerators. + OS << R"c++( +#ifdef GET_BUILTIN_ENUMERATORS +)c++"; + for (const auto &B : Builtins) + B.EmitEnumerator(OS); + OS << R"c++( +#endif // GET_BUILTIN_ENUMERATORS +)c++"; + + // Emit a string table that can be referenced for these builtins. + OS << R"c++( +#ifdef GET_BUILTIN_STR_TABLE +)c++"; + Table.EmitStringTableDef(OS, "BuiltinStrings"); + OS << R"c++( +#endif // GET_BUILTIN_STR_TABLE +)c++"; + // Emit a direct set of `Builtin::Info` initializers, first for the unprefixed + // builtins and then for the prefixed builtins. + OS << R"c++( +#ifdef GET_BUILTIN_INFOS +)c++"; + for (const auto &B : UnprefixedBuiltins) + B.EmitInfo(OS, Table); + OS << R"c++( +#endif // GET_BUILTIN_INFOS +)c++"; + + OS << R"c++( +#ifdef GET_BUILTIN_PREFIXED_INFOS +)c++"; + for (const auto &B : PrefixedBuiltins) + B.EmitInfo(OS, Table); + OS << R"c++( +#endif // GET_BUILTIN_PREFIXED_INFOS +)c++"; + + // Emit X-macros for the atomic builtins to support various custome patterns + // used exclusively with those builtins. + // + // FIXME: We should eventually move this to a separate file so that users + // don't need to include the full set of builtins. + OS << R"c++( +#ifdef ATOMIC_BUILTIN +)c++"; + for (const auto &Builtin : AtomicBuiltins) { + Builtin.EmitXMacro(OS); + } OS << R"c++( +#endif // ATOMIC_BUILTIN #undef ATOMIC_BUILTIN -#undef BUILTIN -#undef LIBBUILTIN -#undef LANGBUILTIN -#undef TARGET_BUILTIN -#undef TARGET_HEADER_BUILTIN )c++"; } diff --git a/clang/utils/TableGen/MveEmitter.cpp b/clang/utils/TableGen/MveEmitter.cpp index 58a4d3c22ac36..e77679876a3af 100644 --- a/clang/utils/TableGen/MveEmitter.cpp +++ b/clang/utils/TableGen/MveEmitter.cpp @@ -1949,26 +1949,53 @@ void MveEmitter::EmitHeader(raw_ostream &OS) { } void MveEmitter::EmitBuiltinDef(raw_ostream &OS) { - for (const auto &kv : ACLEIntrinsics) { - const ACLEIntrinsic &Int = *kv.second; - OS << "BUILTIN(__builtin_arm_mve_" << Int.fullName() - << ", \"\", \"n\")\n"; + llvm::StringToOffsetTable Table; + Table.GetOrAddStringOffset("n"); + Table.GetOrAddStringOffset("nt"); + Table.GetOrAddStringOffset("ntu"); + Table.GetOrAddStringOffset("vi."); + + for (const auto &[_, Int] : ACLEIntrinsics) + Table.GetOrAddStringOffset(Int->fullName()); + + std::map ShortNameIntrinsics; + for (const auto &[_, Int] : ACLEIntrinsics) { + if (!Int->polymorphic()) + continue; + + StringRef Name = Int->shortName(); + if (ShortNameIntrinsics.insert({Name.str(), Int.get()}).second) + Table.GetOrAddStringOffset(Name); } - DenseSet ShortNamesSeen; + OS << "#ifdef GET_MVE_BUILTIN_ENUMERATORS\n"; + for (const auto &[_, Int] : ACLEIntrinsics) { + OS << " BI__builtin_arm_mve_" << Int->fullName() << ",\n"; + } + for (const auto &[Name, _] : ShortNameIntrinsics) { + OS << " BI__builtin_arm_mve_" << Name << ",\n"; + } + OS << "#endif // GET_MVE_BUILTIN_ENUMERATORS\n\n"; - for (const auto &kv : ACLEIntrinsics) { - const ACLEIntrinsic &Int = *kv.second; - if (Int.polymorphic()) { - StringRef Name = Int.shortName(); - if (ShortNamesSeen.insert(Name).second) { - OS << "BUILTIN(__builtin_arm_mve_" << Name << ", \"vi.\", \"nt"; - if (Int.nonEvaluating()) - OS << "u"; // indicate that this builtin doesn't evaluate its args - OS << "\")\n"; - } - } + OS << "#ifdef GET_MVE_BUILTIN_STR_TABLE\n"; + Table.EmitStringTableDef(OS, "BuiltinStrings"); + OS << "#endif // GET_MVE_BUILTIN_STR_TABLE\n\n"; + + OS << "#ifdef GET_MVE_BUILTIN_INFOS\n"; + for (const auto &[_, Int] : ACLEIntrinsics) { + OS << " Builtin::Info{Builtin::Info::StrOffsets{" + << Table.GetStringOffset(Int->fullName()) << " /* " << Int->fullName() + << " */, " << Table.GetStringOffset("") << ", " + << Table.GetStringOffset("n") << " /* n */}},\n"; + } + for (const auto &[Name, Int] : ShortNameIntrinsics) { + StringRef Attrs = Int->nonEvaluating() ? "ntu" : "nt"; + OS << " Builtin::Info{Builtin::Info::StrOffsets{" + << Table.GetStringOffset(Name) << " /* " << Name << " */, " + << Table.GetStringOffset("vi.") << " /* vi. */, " + << Table.GetStringOffset(Attrs) << " /* " << Attrs << " */}},\n"; } + OS << "#endif // GET_MVE_BUILTIN_INFOS\n\n"; } void MveEmitter::EmitBuiltinSema(raw_ostream &OS) { @@ -2156,13 +2183,31 @@ void CdeEmitter::EmitHeader(raw_ostream &OS) { } void CdeEmitter::EmitBuiltinDef(raw_ostream &OS) { - for (const auto &kv : ACLEIntrinsics) { - if (kv.second->headerOnly()) - continue; - const ACLEIntrinsic &Int = *kv.second; - OS << "BUILTIN(__builtin_arm_cde_" << Int.fullName() - << ", \"\", \"ncU\")\n"; - } + llvm::StringToOffsetTable Table; + Table.GetOrAddStringOffset("ncU"); + + for (const auto &[_, Int] : ACLEIntrinsics) + if (!Int->headerOnly()) + Table.GetOrAddStringOffset(Int->fullName()); + + OS << "#ifdef GET_CDE_BUILTIN_ENUMERATORS\n"; + for (const auto &[_, Int] : ACLEIntrinsics) + if (!Int->headerOnly()) + OS << " BI__builtin_arm_cde_" << Int->fullName() << ",\n"; + OS << "#endif // GET_CDE_BUILTIN_ENUMERATORS\n\n"; + + OS << "#ifdef GET_CDE_BUILTIN_STR_TABLE\n"; + Table.EmitStringTableDef(OS, "BuiltinStrings"); + OS << "#endif // GET_CDE_BUILTIN_STR_TABLE\n\n"; + + OS << "#ifdef GET_CDE_BUILTIN_INFOS\n"; + for (const auto &[_, Int] : ACLEIntrinsics) + if (!Int->headerOnly()) + OS << " Builtin::Info{Builtin::Info::StrOffsets{" + << Table.GetStringOffset(Int->fullName()) << " /* " << Int->fullName() + << " */, " << Table.GetStringOffset("") << ", " + << Table.GetStringOffset("ncU") << " /* ncU */}},\n"; + OS << "#endif // GET_CDE_BUILTIN_INFOS\n\n"; } void CdeEmitter::EmitBuiltinSema(raw_ostream &OS) { diff --git a/clang/utils/TableGen/NeonEmitter.cpp b/clang/utils/TableGen/NeonEmitter.cpp index 295e7eb89c967..a18f78697af1c 100644 --- a/clang/utils/TableGen/NeonEmitter.cpp +++ b/clang/utils/TableGen/NeonEmitter.cpp @@ -37,6 +37,7 @@ #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/SetTheory.h" +#include "llvm/TableGen/StringToOffsetTable.h" #include #include #include @@ -2061,40 +2062,51 @@ void NeonEmitter::createIntrinsic(const Record *R, CurrentRecord = nullptr; } -/// genBuiltinsDef: Generate the BuiltinsARM.def and BuiltinsAArch64.def -/// declaration of builtins, checking for unique builtin declarations. +/// genBuiltinsDef: Generate the builtin infos, checking for unique builtin +/// declarations. void NeonEmitter::genBuiltinsDef(raw_ostream &OS, SmallVectorImpl &Defs) { - OS << "#ifdef GET_NEON_BUILTINS\n"; + // We only want to emit a builtin once, and in order of its name. + std::map Builtins; - // We only want to emit a builtin once, and we want to emit them in - // alphabetical order, so use a std::set. - std::set> Builtins; + llvm::StringToOffsetTable Table; + Table.GetOrAddStringOffset(""); + Table.GetOrAddStringOffset("n"); for (auto *Def : Defs) { if (Def->hasBody()) continue; - std::string S = "__builtin_neon_" + Def->getMangledName() + ", \""; - S += Def->getBuiltinTypeStr(); - S += "\", \"n\""; - - Builtins.emplace(S, Def->getTargetGuard()); + if (Builtins.insert({Def->getMangledName(), Def}).second) { + Table.GetOrAddStringOffset(Def->getMangledName()); + Table.GetOrAddStringOffset(Def->getBuiltinTypeStr()); + Table.GetOrAddStringOffset(Def->getTargetGuard()); + } } - for (auto &S : Builtins) { - if (S.second == "") - OS << "BUILTIN("; - else - OS << "TARGET_BUILTIN("; - OS << S.first; - if (S.second == "") - OS << ")\n"; - else - OS << ", \"" << S.second << "\")\n"; + OS << "#ifdef GET_NEON_BUILTIN_ENUMERATORS\n"; + for (const auto &[Name, Def] : Builtins) { + OS << " BI__builtin_neon_" << Name << ",\n"; } + OS << "#endif // GET_NEON_BUILTIN_ENUMERATORS\n\n"; - OS << "#endif\n\n"; + OS << "#ifdef GET_NEON_BUILTIN_STR_TABLE\n"; + Table.EmitStringTableDef(OS, "BuiltinStrings"); + OS << "#endif // GET_NEON_BUILTIN_STR_TABLE\n\n"; + + OS << "#ifdef GET_NEON_BUILTIN_INFOS\n"; + for (const auto &[Name, Def] : Builtins) { + OS << " Builtin::Info{Builtin::Info::StrOffsets{" + << Table.GetStringOffset(Def->getMangledName()) << " /* " + << Def->getMangledName() << " */, "; + OS << Table.GetStringOffset(Def->getBuiltinTypeStr()) << " /* " + << Def->getBuiltinTypeStr() << " */, "; + OS << Table.GetStringOffset("n") << " /* n */, "; + OS << Table.GetStringOffset(Def->getTargetGuard()) << " /* " + << Def->getTargetGuard() << " */}, "; + OS << "HeaderDesc::NO_HEADER, ALL_LANGUAGES},\n"; + } + OS << "#endif // GET_NEON_BUILTIN_INFOS\n\n"; } void NeonEmitter::genStreamingSVECompatibleList( diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp index acba1a3191281..0cdde20060b63 100644 --- a/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -18,10 +18,12 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringToOffsetTable.h" #include using namespace llvm; @@ -498,31 +500,68 @@ void RVVEmitter::createBuiltins(raw_ostream &OS) { std::vector> Defs; createRVVIntrinsics(Defs); - // Map to keep track of which builtin names have already been emitted. - StringMap BuiltinMap; + llvm::StringToOffsetTable Table; + // Ensure offset zero is the empty string. + Table.GetOrAddStringOffset(""); + // Hard coded strings used in the builtin structures. + Table.GetOrAddStringOffset("n"); + Table.GetOrAddStringOffset("zve32x"); - OS << "#if defined(TARGET_BUILTIN) && !defined(RISCVV_BUILTIN)\n"; - OS << "#define RISCVV_BUILTIN(ID, TYPE, ATTRS) TARGET_BUILTIN(ID, TYPE, " - "ATTRS, \"zve32x\")\n"; - OS << "#endif\n"; + // Map to unique the builtin names. + StringMap BuiltinMap; + std::vector UniqueDefs; for (auto &Def : Defs) { - auto P = - BuiltinMap.insert(std::make_pair(Def->getBuiltinName(), Def.get())); - if (!P.second) { - // Verf that this would have produced the same builtin definition. - if (P.first->second->hasBuiltinAlias() != Def->hasBuiltinAlias()) - PrintFatalError("Builtin with same name has different hasAutoDef"); - else if (!Def->hasBuiltinAlias() && - P.first->second->getBuiltinTypeStr() != Def->getBuiltinTypeStr()) - PrintFatalError("Builtin with same name has different type string"); + auto P = BuiltinMap.insert({Def->getBuiltinName(), Def.get()}); + if (P.second) { + Table.GetOrAddStringOffset(Def->getBuiltinName()); + if (!Def->hasBuiltinAlias()) + Table.GetOrAddStringOffset(Def->getBuiltinTypeStr()); + UniqueDefs.push_back(Def.get()); continue; } - OS << "RISCVV_BUILTIN(__builtin_rvv_" << Def->getBuiltinName() << ",\""; - if (!Def->hasBuiltinAlias()) - OS << Def->getBuiltinTypeStr(); - OS << "\", \"n\")\n"; + + // Verf that this would have produced the same builtin definition. + if (P.first->second->hasBuiltinAlias() != Def->hasBuiltinAlias()) + PrintFatalError("Builtin with same name has different hasAutoDef"); + else if (!Def->hasBuiltinAlias() && + P.first->second->getBuiltinTypeStr() != Def->getBuiltinTypeStr()) + PrintFatalError("Builtin with same name has different type string"); + } + + // Emit the enumerators of RVV builtins. Note that these are emitted without + // any outer context to enable concatenating them. + OS << "// RISCV Vector builtin enumerators\n"; + OS << "#ifdef GET_RISCVV_BUILTIN_ENUMERATORS\n"; + for (RVVIntrinsic *Def : UniqueDefs) + OS << " BI__builtin_rvv_" << Def->getBuiltinName() << ",\n"; + OS << "#endif // GET_RISCVV_BUILTIN_ENUMERATORS\n\n"; + + // Emit the string table for the RVV builtins. + OS << "// RISCV Vector builtin enumerators\n"; + OS << "#ifdef GET_RISCVV_BUILTIN_STR_TABLE\n"; + Table.EmitStringTableDef(OS, "BuiltinStrings"); + OS << "#endif // GET_RISCVV_BUILTIN_STR_TABLE\n\n"; + + // Emit the info structs of RVV builtins. Note that these are emitted without + // any outer context to enable concatenating them. + OS << "// RISCV Vector builtin infos\n"; + OS << "#ifdef GET_RISCVV_BUILTIN_INFOS\n"; + for (RVVIntrinsic *Def : UniqueDefs) { + OS << " Builtin::Info{Builtin::Info::StrOffsets{" + << Table.GetStringOffset(Def->getBuiltinName()) << " /* " + << Def->getBuiltinName() << " */, "; + if (Def->hasBuiltinAlias()) { + OS << "0, "; + } else { + OS << Table.GetStringOffset(Def->getBuiltinTypeStr()) << " /* " + << Def->getBuiltinTypeStr() << " */, "; + } + OS << Table.GetStringOffset("n") << " /* n */, "; + OS << Table.GetStringOffset("zve32x") << " /* zve32x */}, "; + + OS << "HeaderDesc::NO_HEADER, ALL_LANGUAGES},\n"; } - OS << "#undef RISCVV_BUILTIN\n"; + OS << "#endif // GET_RISCVV_BUILTIN_INFOS\n\n"; } void RVVEmitter::createCodeGen(raw_ostream &OS) { diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp index 39dcbc678dc48..e226987b4844b 100644 --- a/clang/utils/TableGen/SveEmitter.cpp +++ b/clang/utils/TableGen/SveEmitter.cpp @@ -27,9 +27,11 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/AArch64ImmCheck.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringToOffsetTable.h" #include #include #include @@ -200,7 +202,9 @@ class Intrinsic { StringRef getSVEGuard() const { return SVEGuard; } StringRef getSMEGuard() const { return SMEGuard; } - void printGuard(raw_ostream &OS) const { + std::string getGuard() const { + std::string Guard; + llvm::raw_string_ostream OS(Guard); if (!SVEGuard.empty() && SMEGuard.empty()) OS << SVEGuard; else if (SVEGuard.empty() && !SMEGuard.empty()) @@ -218,6 +222,7 @@ class Intrinsic { else OS << SMEGuard; } + return Guard; } ClassKind getClassKind() const { return Class; } @@ -1479,19 +1484,19 @@ void SVEEmitter::createBuiltins(raw_ostream &OS) { return A->getMangledName() < B->getMangledName(); }); - OS << "#ifdef GET_SVE_BUILTINS\n"; - for (auto &Def : Defs) { - // Only create BUILTINs for non-overloaded intrinsics, as overloaded - // declarations only live in the header file. + llvm::StringToOffsetTable Table; + Table.GetOrAddStringOffset(""); + Table.GetOrAddStringOffset("n"); + + for (const auto &Def : Defs) if (Def->getClassKind() != ClassG) { - OS << "TARGET_BUILTIN(__builtin_sve_" << Def->getMangledName() << ", \"" - << Def->getBuiltinTypeStr() << "\", \"n\", \""; - Def->printGuard(OS); - OS << "\")\n"; + Table.GetOrAddStringOffset(Def->getMangledName()); + Table.GetOrAddStringOffset(Def->getBuiltinTypeStr()); + Table.GetOrAddStringOffset(Def->getGuard()); } - } - // Add reinterpret functions. + Table.GetOrAddStringOffset("sme|sve"); + SmallVector> ReinterpretBuiltins; for (auto [N, Suffix] : std::initializer_list>{ {1, ""}, {2, "_x2"}, {3, "_x3"}, {4, "_x4"}}) { @@ -1499,14 +1504,54 @@ void SVEEmitter::createBuiltins(raw_ostream &OS) { SVEType ToV(To.BaseType, N); for (const ReinterpretTypeInfo &From : Reinterprets) { SVEType FromV(From.BaseType, N); - OS << "TARGET_BUILTIN(__builtin_sve_reinterpret_" << To.Suffix << "_" - << From.Suffix << Suffix << +", \"" << ToV.builtin_str() - << FromV.builtin_str() << "\", \"n\", \"sme|sve\")\n"; + std::string Name = + (Twine("reinterpret_") + To.Suffix + "_" + From.Suffix + Suffix) + .str(); + std::string Type = ToV.builtin_str() + FromV.builtin_str(); + Table.GetOrAddStringOffset(Name); + Table.GetOrAddStringOffset(Type); + ReinterpretBuiltins.push_back({Name, Type}); } } } - OS << "#endif\n\n"; + OS << "#ifdef GET_SVE_BUILTIN_ENUMERATORS\n"; + for (const auto &Def : Defs) + if (Def->getClassKind() != ClassG) + OS << " BI__builtin_sve_" << Def->getMangledName() << ",\n"; + for (const auto &[Name, _] : ReinterpretBuiltins) + OS << " BI__builtin_sve_" << Name << ",\n"; + OS << "#endif // GET_SVE_BUILTIN_ENUMERATORS\n\n"; + + OS << "#ifdef GET_SVE_BUILTIN_STR_TABLE\n"; + Table.EmitStringTableDef(OS, "BuiltinStrings"); + OS << "#endif // GET_SVE_BUILTIN_STR_TABLE\n\n"; + + OS << "#ifdef GET_SVE_BUILTIN_INFOS\n"; + for (const auto &Def : Defs) { + // Only create BUILTINs for non-overloaded intrinsics, as overloaded + // declarations only live in the header file. + if (Def->getClassKind() != ClassG) { + OS << " Builtin::Info{Builtin::Info::StrOffsets{" + << Table.GetStringOffset(Def->getMangledName()) << " /* " + << Def->getMangledName() << " */, "; + OS << Table.GetStringOffset(Def->getBuiltinTypeStr()) << " /* " + << Def->getBuiltinTypeStr() << " */, "; + OS << Table.GetStringOffset("n") << " /* n */, "; + OS << Table.GetStringOffset(Def->getGuard()) << " /* " << Def->getGuard() + << " */}, "; + OS << "HeaderDesc::NO_HEADER, ALL_LANGUAGES},\n"; + } + } + for (const auto &[Name, Type] : ReinterpretBuiltins) { + OS << " Builtin::Info{Builtin::Info::StrOffsets{" + << Table.GetStringOffset(Name) << " /* " << Name << " */, "; + OS << Table.GetStringOffset(Type) << " /* " << Type << " */, "; + OS << Table.GetStringOffset("n") << " /* n */, "; + OS << Table.GetStringOffset("sme|sve") << " /* sme|sve */}, "; + OS << "HeaderDesc::NO_HEADER, ALL_LANGUAGES},\n"; + } + OS << "#endif // GET_SVE_BUILTIN_INFOS\n\n"; } void SVEEmitter::createCodeGenMap(raw_ostream &OS) { @@ -1679,19 +1724,44 @@ void SVEEmitter::createSMEBuiltins(raw_ostream &OS) { return A->getMangledName() < B->getMangledName(); }); - OS << "#ifdef GET_SME_BUILTINS\n"; - for (auto &Def : Defs) { + llvm::StringToOffsetTable Table; + Table.GetOrAddStringOffset(""); + Table.GetOrAddStringOffset("n"); + + for (const auto &Def : Defs) + if (Def->getClassKind() != ClassG) { + Table.GetOrAddStringOffset(Def->getMangledName()); + Table.GetOrAddStringOffset(Def->getBuiltinTypeStr()); + Table.GetOrAddStringOffset(Def->getGuard()); + } + + OS << "#ifdef GET_SME_BUILTIN_ENUMERATORS\n"; + for (const auto &Def : Defs) + if (Def->getClassKind() != ClassG) + OS << " BI__builtin_sme_" << Def->getMangledName() << ",\n"; + OS << "#endif // GET_SME_BUILTIN_ENUMERATORS\n\n"; + + OS << "#ifdef GET_SME_BUILTIN_STR_TABLE\n"; + Table.EmitStringTableDef(OS, "BuiltinStrings"); + OS << "#endif // GET_SME_BUILTIN_STR_TABLE\n\n"; + + OS << "#ifdef GET_SME_BUILTIN_INFOS\n"; + for (const auto &Def : Defs) { // Only create BUILTINs for non-overloaded intrinsics, as overloaded // declarations only live in the header file. if (Def->getClassKind() != ClassG) { - OS << "TARGET_BUILTIN(__builtin_sme_" << Def->getMangledName() << ", \"" - << Def->getBuiltinTypeStr() << "\", \"n\", \""; - Def->printGuard(OS); - OS << "\")\n"; + OS << " Builtin::Info{Builtin::Info::StrOffsets{" + << Table.GetStringOffset(Def->getMangledName()) << " /* " + << Def->getMangledName() << " */, "; + OS << Table.GetStringOffset(Def->getBuiltinTypeStr()) << " /* " + << Def->getBuiltinTypeStr() << " */, "; + OS << Table.GetStringOffset("n") << " /* n */, "; + OS << Table.GetStringOffset(Def->getGuard()) << " /* " << Def->getGuard() + << " */}, "; + OS << "HeaderDesc::NO_HEADER, ALL_LANGUAGES},\n"; } } - - OS << "#endif\n\n"; + OS << "#endif // GET_SME_BUILTIN_INFOS\n\n"; } void SVEEmitter::createSMECodeGenMap(raw_ostream &OS) {