From cd269fee05a0f78fb53b65f701b4e06e9ddab424 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 14 Dec 2024 09:09:47 +0000 Subject: [PATCH] [StrTable] Switch Clang builtins to use string tables This both reapplies #118734, the initial attempt at this, and updates it significantly. First, it uses the newly added `StringTable` abstraction for string tables, and simplifies the construction to build the string table and info arrays separately. This should reduce any `constexpr` compile time memory or CPU cost of the original PR while significantly improving the APIs throughout. It also restructures the builtins to support sharding across several independent tables. This accomplishes two improvements from the original PR: 1) It improves the APIs used significantly. 2) When builtins are defined from different sources (like SVE vs MVE in AArch64), this allows each of them to build their own string table independently rather than having to merge the string tables and info structures. 3) It allows each shard to factor out a common prefix, often cutting the size of the strings needed for the builtins by a factor two. The second point is important both to allow different mechanisms of construction (for example a `.def` file and a tablegen'ed `.inc` file, or different tablegen'ed `.inc files), it also simply reduces the sizes of these tables which is valuable given how large they are in some cases. The third builds on that size reduction. Initially, we use this new sharding rather than merging tables in AArch64, LoongArch, RISCV, and X86. Mostly this helps ensure the system works, as without further changes these still push scaling limits. Subsequent commits will more deeply leverage the new structure, including using the prefix capabilities which cannot be easily factored out here and requires deep changes to the targets. --- clang/include/clang/Basic/Builtins.h | 227 +++++++++++++++--- .../include/clang/Basic/BuiltinsLoongArch.def | 28 --- clang/include/clang/Basic/BuiltinsPPC.def | 1 + clang/include/clang/Basic/TargetBuiltins.h | 12 +- clang/include/clang/Basic/TargetInfo.h | 10 +- clang/include/module.modulemap | 1 - clang/lib/Basic/Builtins.cpp | 182 ++++++++++---- clang/lib/Basic/Targets/AArch64.cpp | 93 ++++--- clang/lib/Basic/Targets/AArch64.h | 2 +- clang/lib/Basic/Targets/AMDGPU.cpp | 26 +- clang/lib/Basic/Targets/AMDGPU.h | 2 +- clang/lib/Basic/Targets/ARC.h | 4 +- clang/lib/Basic/Targets/ARM.cpp | 48 ++-- clang/lib/Basic/Targets/ARM.h | 2 +- clang/lib/Basic/Targets/AVR.h | 4 +- clang/lib/Basic/Targets/BPF.cpp | 22 +- clang/lib/Basic/Targets/BPF.h | 2 +- clang/lib/Basic/Targets/CSKY.cpp | 4 - clang/lib/Basic/Targets/CSKY.h | 4 +- clang/lib/Basic/Targets/DirectX.h | 4 +- clang/lib/Basic/Targets/Hexagon.cpp | 29 ++- clang/lib/Basic/Targets/Hexagon.h | 2 +- clang/lib/Basic/Targets/Lanai.h | 4 +- clang/lib/Basic/Targets/LoongArch.cpp | 66 ++++- clang/lib/Basic/Targets/LoongArch.h | 2 +- clang/lib/Basic/Targets/M68k.cpp | 3 +- clang/lib/Basic/Targets/M68k.h | 2 +- clang/lib/Basic/Targets/MSP430.h | 2 +- clang/lib/Basic/Targets/Mips.cpp | 25 +- clang/lib/Basic/Targets/Mips.h | 2 +- clang/lib/Basic/Targets/NVPTX.cpp | 22 +- clang/lib/Basic/Targets/NVPTX.h | 2 +- clang/lib/Basic/Targets/PNaCl.h | 4 +- clang/lib/Basic/Targets/PPC.cpp | 29 ++- clang/lib/Basic/Targets/PPC.h | 2 +- clang/lib/Basic/Targets/RISCV.cpp | 52 ++-- clang/lib/Basic/Targets/RISCV.h | 2 +- clang/lib/Basic/Targets/SPIR.cpp | 27 ++- clang/lib/Basic/Targets/SPIR.h | 10 +- clang/lib/Basic/Targets/Sparc.h | 2 +- clang/lib/Basic/Targets/SystemZ.cpp | 26 +- clang/lib/Basic/Targets/SystemZ.h | 2 +- clang/lib/Basic/Targets/TCE.h | 4 +- clang/lib/Basic/Targets/VE.cpp | 21 +- clang/lib/Basic/Targets/VE.h | 2 +- clang/lib/Basic/Targets/WebAssembly.cpp | 29 ++- clang/lib/Basic/Targets/WebAssembly.h | 2 +- clang/lib/Basic/Targets/X86.cpp | 66 +++-- clang/lib/Basic/Targets/X86.h | 4 +- clang/lib/Basic/Targets/XCore.cpp | 25 +- clang/lib/Basic/Targets/XCore.h | 2 +- clang/lib/Basic/Targets/Xtensa.h | 4 +- clang/lib/CodeGen/CGBuiltin.cpp | 10 +- clang/lib/CodeGen/CodeGenModule.cpp | 3 +- clang/lib/Sema/SemaChecking.cpp | 16 +- clang/lib/Sema/SemaExpr.cpp | 2 +- .../StaticAnalyzer/Core/CheckerContext.cpp | 2 +- 57 files changed, 818 insertions(+), 369 deletions(-) delete mode 100644 clang/include/clang/Basic/BuiltinsLoongArch.def diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h index 63559d977ce6..ba9108dfe7fc 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; @@ -68,14 +70,153 @@ enum ID { 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 +224,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 +246,17 @@ public: /// 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 +265,40 @@ public: /// 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 +309,21 @@ public: /// 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 +331,7 @@ public: /// 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 +345,33 @@ public: /// 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 +396,25 @@ public: /// 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 +426,19 @@ public: /// 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/BuiltinsLoongArch.def b/clang/include/clang/Basic/BuiltinsLoongArch.def deleted file mode 100644 index 95359a3fdc71..000000000000 --- 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/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index 161df386f00f..bb7d54bbb793 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/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 95eb110bb9c2..2a9f9a7dd422 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -178,8 +178,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 diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index d762144478b4..77c2f88a172d 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 @@ public: 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 b318bd95ee67..e2bc941d3143 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/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp index 588183788de3..e5b0ff536113 100644 --- a/clang/lib/Basic/Builtins.cpp +++ b/clang/lib/Basic/Builtins.cpp @@ -29,54 +29,124 @@ 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 llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START + // We inject a non-builtin string into the table. + CLANG_BUILTIN_STR_TABLE("not a builtin function", "", "") +#define BUILTIN CLANG_BUILTIN_STR_TABLE #include "clang/Basic/Builtins.inc" -}; + ; +static_assert(BuiltinStrings.size() < 100'000); -const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const { - if (ID < Builtin::FirstTSBuiltin) - return BuiltinInfo[ID]; - assert(((ID - Builtin::FirstTSBuiltin) < - (TSRecords.size() + AuxTSRecords.size())) && +static constexpr auto BuiltinInfos = + Builtin::MakeInfos( + {CLANG_BUILTIN_ENTRY("not a builtin function", "", "") +#define BUILTIN CLANG_BUILTIN_ENTRY +#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY +#include "clang/Basic/Builtins.inc" + }); + +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 +193,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 +202,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); - } + 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 (unsigned i = 0, e = TSRecords.size(); i != e; ++i) - if (builtinIsSupported(TSRecords[i], LangOpts)) - Table.get(TSRecords[i].Name).setBuiltinID(i + Builtin::FirstTSBuiltin); + // 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 +245,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 +269,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 +296,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 57c9849ef2a7..38238840e52f 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -26,35 +26,67 @@ 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 NumNEONBuiltins = + NEON::FirstTSBuiltin - Builtin::FirstTSBuiltin; +static constexpr int NumSVEBuiltins = + SVE::FirstTSBuiltin - NEON::FirstTSBuiltin; +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 + NumSVEBuiltins + + NumSMEBuiltins + NumAArch64Builtins)); + +static constexpr llvm::StringTable BuiltinNEONStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE #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}, + ; +static constexpr llvm::StringTable BuiltinSVEStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE #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}, + ; +static constexpr llvm::StringTable BuiltinSMEStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE #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}, + ; +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 BuiltinNEONInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsNEON.def" +}); +static constexpr auto BuiltinSVEInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsSVE.def" +}); +static constexpr auto BuiltinSMEInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsSME.def" +}); +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 +729,14 @@ 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 { + {&BuiltinNEONStrings, BuiltinNEONInfos}, + {&BuiltinSVEStrings, BuiltinSVEInfos}, + {&BuiltinSMEStrings, BuiltinSMEInfos}, + {&BuiltinAArch64Strings, BuiltinAArch64Infos}, + }; } std::optional> diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 79e012f48e65..f2510adb0ea2 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -181,7 +181,7 @@ public: 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 0d308cb6af96..228f967caf2f 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 ea4189cdea47..3d6778fb5a76 100644 --- a/clang/lib/Basic/Targets/AMDGPU.h +++ b/clang/lib/Basic/Targets/AMDGPU.h @@ -257,7 +257,7 @@ public: 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 7f3d0aa15ab8..2b69f95591fa 100644 --- a/clang/lib/Basic/Targets/ARC.h +++ b/clang/lib/Basic/Targets/ARC.h @@ -40,7 +40,9 @@ public: 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 5aa2baeb81b7..2b1ab92c22ca 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -1074,31 +1074,37 @@ 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}, +static constexpr int NumBuiltins = + clang::ARM::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/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}, +#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" -}; + ; -ArrayRef ARMTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin); +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsNEON.def" +#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 {{&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 5f4acce7af5a..22033a6da338 100644 --- a/clang/lib/Basic/Targets/ARM.h +++ b/clang/lib/Basic/Targets/ARM.h @@ -196,7 +196,7 @@ public: 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 df1f8d171efb..2117ab58e6f3 100644 --- a/clang/lib/Basic/Targets/AVR.h +++ b/clang/lib/Basic/Targets/AVR.h @@ -63,7 +63,9 @@ public: 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 f4684765b7ff..b4504faa4d5e 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; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsBPF.inc" -}; + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsBPF.inc" +}); 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 27a4b5f31497..d1f68b842348 100644 --- a/clang/lib/Basic/Targets/BPF.h +++ b/clang/lib/Basic/Targets/BPF.h @@ -58,7 +58,7 @@ public: 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 c8bf8b9234d2..e698508a2370 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 94d4eeb9a1ff..ddfbe4794daa 100644 --- a/clang/lib/Basic/Targets/CSKY.h +++ b/clang/lib/Basic/Targets/CSKY.h @@ -73,7 +73,9 @@ public: 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 4e6bc0e04039..6e3ddad62634 100644 --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -73,7 +73,9 @@ public: 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 2e173e01ed8e..acf44efb76e5 100644 --- a/clang/lib/Basic/Targets/Hexagon.cpp +++ b/clang/lib/Basic/Targets/Hexagon.cpp @@ -204,15 +204,22 @@ 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; + +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/BuiltinsHexagon.inc" -}; + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsHexagon.inc" +}); bool HexagonTargetInfo::hasFeature(StringRef Feature) const { std::string VS = "hvxv" + HVXVersion; @@ -271,7 +278,7 @@ 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}}; } diff --git a/clang/lib/Basic/Targets/Hexagon.h b/clang/lib/Basic/Targets/Hexagon.h index 7f053ab7e488..a65663ca09ee 100644 --- a/clang/lib/Basic/Targets/Hexagon.h +++ b/clang/lib/Basic/Targets/Hexagon.h @@ -66,7 +66,7 @@ public: 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 f7e439c7c9e1..e32ef9d7d40d 100644 --- a/clang/lib/Basic/Targets/Lanai.h +++ b/clang/lib/Basic/Targets/Lanai.h @@ -78,7 +78,9 @@ public: 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 bb0d0b68cfcb..ca742797d7a3 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 5c34c84ff8d3..4c7b53abfef9 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -72,7 +72,7 @@ public: 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 b5b29fd86756..e5b7f06829cd 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 b732add77e03..729d79ff77fb 100644 --- a/clang/lib/Basic/Targets/M68k.h +++ b/clang/lib/Basic/Targets/M68k.h @@ -44,7 +44,7 @@ public: 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 2266ada25c1d..d7d05f992f4f 100644 --- a/clang/lib/Basic/Targets/MSP430.h +++ b/clang/lib/Basic/Targets/MSP430.h @@ -50,7 +50,7 @@ public: 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 d56995e3ccc4..866be53c8a36 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 7ddcd57053cb..35501ed44ccd 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -198,7 +198,7 @@ public: 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 017146a9ada1..f20c0217d560 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; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsNVPTX.inc" -}; + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsNVPTX.inc" +}); const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"}; @@ -295,7 +303,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 c6531148fe30..6a868c42e126 100644 --- a/clang/lib/Basic/Targets/NVPTX.h +++ b/clang/lib/Basic/Targets/NVPTX.h @@ -75,7 +75,7 @@ public: 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 7e0e10aa362d..d162776b5a0d 100644 --- a/clang/lib/Basic/Targets/PNaCl.h +++ b/clang/lib/Basic/Targets/PNaCl.h @@ -52,7 +52,9 @@ public: 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 1448069173b5..2d8891a739ca 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 3cd0fcad1729..db6ac6f0bd33 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -187,7 +187,7 @@ public: 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 61b8ae9d098a..a63796d2f5a1 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -240,22 +240,44 @@ 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 = + clang::RISCVVector::FirstTSBuiltin - Builtin::FirstTSBuiltin; +static constexpr int NumRISCVBuiltins = + clang::RISCV::LastTSBuiltin - RISCVVector::FirstTSBuiltin; +static constexpr int NumBuiltins = + clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin; +static_assert(NumBuiltins == (NumRVVBuiltins + NumRISCVBuiltins)); -ArrayRef RISCVTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin); +static constexpr llvm::StringTable BuiltinRVVStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsRISCVVector.def" + ; +static constexpr llvm::StringTable BuiltinRISCVStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsRISCV.inc" + ; + +static constexpr auto BuiltinRVVInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsRISCVVector.def" +}); +static constexpr auto BuiltinRISCVInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsRISCV.inc" +}); + +llvm::SmallVector +RISCVTargetInfo::getTargetBuiltins() const { + return { + {&BuiltinRVVStrings, BuiltinRVVInfos}, + {&BuiltinRISCVStrings, BuiltinRISCVInfos}, + }; } bool RISCVTargetInfo::initFeatureMap( diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h index d31c46f2bb16..c26aa1908016 100644 --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -62,7 +62,7 @@ public: 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 f242fedc1ad6..a242fd8c4b5c 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}, -#include "clang/Basic/BuiltinsSPIRV.inc" -}; +static constexpr int NumBuiltins = + clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin; -ArrayRef SPIRVTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin); +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsSPIRV.inc" + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsSPIRV.inc" +}); + +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 c0849b69dcdb..61f9ef7e3e36 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -161,7 +161,9 @@ public: // 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 @@ public: 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 @@ public: 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 9c529a5bc5e7..3215e648ba6c 100644 --- a/clang/lib/Basic/Targets/Sparc.h +++ b/clang/lib/Basic/Targets/Sparc.h @@ -48,7 +48,7 @@ public: 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 c836d110d26d..0e9a61c6a01c 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 bd2827cf13a5..4ca3f53f83cb 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -100,7 +100,7 @@ public: 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 edec30bf69de..46c70de8f9ec 100644 --- a/clang/lib/Basic/Targets/TCE.h +++ b/clang/lib/Basic/Targets/TCE.h @@ -96,7 +96,9 @@ public: 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 67cae8faf605..5451f3c30363 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 7e8fdf6096ef..e9b7e92f3f85 100644 --- a/clang/lib/Basic/Targets/VE.h +++ b/clang/lib/Basic/Targets/VE.h @@ -55,7 +55,7 @@ public: 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 7b0fd0c841ba..f19c57f1a3a5 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 cfecc59ac75f..fb48c786a7ed 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -121,7 +121,7 @@ private: 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 40ad8fd9a096..1bb5f78eef71 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -23,23 +23,44 @@ 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}, -#include "clang/Basic/BuiltinsX86.inc" +// 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)); -#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 llvm::StringTable BuiltinX86Strings = + 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/BuiltinsX86.inc" + ; + +static constexpr llvm::StringTable BuiltinX86_64Strings = + 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/BuiltinsX86_64.inc" -}; + ; + +static constexpr auto BuiltinX86Infos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsX86.inc" +}); + +static constexpr auto BuiltinX86_64Infos = + Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsX86_64.inc" + }); static const char *const GCCRegNames[] = { "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", @@ -1856,12 +1877,15 @@ 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 {{&BuiltinX86Strings, BuiltinX86Infos}}; } -ArrayRef X86_64TargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfoX86, - X86::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +X86_64TargetInfo::getTargetBuiltins() const { + return { + {&BuiltinX86Strings, BuiltinX86Infos}, + {&BuiltinX86_64Strings, BuiltinX86_64Infos}, + }; } diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 8bd54e362526..205edcab9ccb 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -509,7 +509,7 @@ public: 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 @@ public: 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 fd377bbfb90e..c725703ede5b 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 84fd59d1a71e..9af9e0658f62 100644 --- a/clang/lib/Basic/Targets/XCore.h +++ b/clang/lib/Basic/Targets/XCore.h @@ -43,7 +43,7 @@ public: 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 a440ba8aa3c6..470835aacff5 100644 --- a/clang/lib/Basic/Targets/Xtensa.h +++ b/clang/lib/Basic/Targets/Xtensa.h @@ -56,8 +56,8 @@ public: 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 11fa295dad95..53f5135eda3a 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()); @@ -21569,7 +21571,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 82002b8d8e4d..02615bb13dfb 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/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 61b2c8cf1cad..b345e40a328b 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; @@ -4584,7 +4586,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 +8381,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 +8547,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 ba4aaa94b90f..3cd4010740d1 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 96464b30c078..d0145293fa3e 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.