From b4b330f465924695a8fddfd51c4f055774fef9fb Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 14 Dec 2024 09:09:47 +0000 Subject: [PATCH 1/6] [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 | 184 ++++++++++---- clang/lib/Basic/Targets/AArch64.cpp | 91 ++++--- 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 | 48 +++- clang/lib/Basic/Targets/RISCV.h | 2 +- clang/lib/Basic/Targets/SPIR.cpp | 25 +- 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 | 64 +++-- 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, 814 insertions(+), 365 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 63559d977ce6b..ba9108dfe7fce 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 @@ 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 +265,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 +309,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 +331,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 +345,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 +396,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 +426,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/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/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/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 95eb110bb9c24..2a9f9a7dd422d 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 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/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp index 588183788de32..e5b0ff5361130 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); + +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" + }); -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 +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); - } - - // 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 +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 57c9849ef2a72..38238840e52f8 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" + ; +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" + ; -#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 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 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..2b1ab92c22ca0 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" -}; + ; + +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" +}); -ArrayRef ARMTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin); +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 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..b4504faa4d5ee 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 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..acf44efb76e55 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 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..9d2d517bc7226 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"}; @@ -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..a63796d2f5a1e 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}, +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)); + +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" -#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 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" -}; + ; -ArrayRef RISCVTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin); +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 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..a242fd8c4b5c8 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; + +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" -}; +}); -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..1bb5f78eef712 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}, +// 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)); + +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" + ; -#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 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 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/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 61b2c8cf1cad7..b345e40a328b5 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 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. From f8cdf409c8243b8b03de1b7912c7e385fdda49ae Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sun, 15 Dec 2024 03:20:15 +0000 Subject: [PATCH 2/6] [StrTable] Switch RISCV to leverage sharded, prefixed builtins w/ TableGen This lets the TableGen-ed code be much cleaner, directly building an efficient string table without duplicates and without the repeated prefix. --- .../clang/Basic/BuiltinsRISCVVector.def | 22 ------ clang/include/clang/Basic/TargetBuiltins.h | 8 +- clang/lib/Basic/Targets/RISCV.cpp | 59 +++++++++----- clang/utils/TableGen/RISCVVEmitter.cpp | 79 ++++++++++++++----- 4 files changed, 104 insertions(+), 64 deletions(-) delete mode 100644 clang/include/clang/Basic/BuiltinsRISCVVector.def 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/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 2a9f9a7dd422d..861be58c67336 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -156,8 +156,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, }; } diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index a63796d2f5a1e..c4317a10d25aa 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -241,32 +241,50 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, } static constexpr int NumRVVBuiltins = - clang::RISCVVector::FirstTSBuiltin - Builtin::FirstTSBuiltin; + RISCVVector::FirstSiFiveBuiltin - Builtin::FirstTSBuiltin; +static constexpr int NumRVVSiFiveBuiltins = + RISCVVector::FirstTSBuiltin - RISCVVector::FirstSiFiveBuiltin; static constexpr int NumRISCVBuiltins = - clang::RISCV::LastTSBuiltin - RISCVVector::FirstTSBuiltin; + RISCV::LastTSBuiltin - RISCVVector::FirstTSBuiltin; static constexpr int NumBuiltins = - clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin; -static_assert(NumBuiltins == (NumRVVBuiltins + NumRISCVBuiltins)); - -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 = + 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 + +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/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({ +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ #define BUILTIN CLANG_BUILTIN_ENTRY #define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY #include "clang/Basic/BuiltinsRISCV.inc" @@ -275,8 +293,9 @@ static constexpr auto BuiltinRISCVInfos = Builtin::MakeInfos({ llvm::SmallVector RISCVTargetInfo::getTargetBuiltins() const { return { - {&BuiltinRVVStrings, BuiltinRVVInfos}, - {&BuiltinRISCVStrings, BuiltinRISCVInfos}, + {&RVV::BuiltinStrings, RVV::BuiltinInfos, "__builtin_rvv_"}, + {&RVVSiFive::BuiltinStrings, RVVSiFive::BuiltinInfos, "__builtin_rvv_"}, + {&BuiltinStrings, BuiltinInfos}, }; } 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) { From 0b24c9b4fbd9be22400ba47d529101c8ba49a81d Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Mon, 16 Dec 2024 20:27:41 +0000 Subject: [PATCH 3/6] [StrTable] Switch AArch64 and ARM to use directly TableGen-ed builtin tables This leverages the sharded structure of the builtins to make it easy to directly tablegen most of the AArch64 and ARM builtins while still using X-macros for a few edge cases. It also extracts common prefixes as part of that. This makes the string tables for these targets dramatically smaller. This is especially important as the SVE builtins represent (by far) the largest string table and largest builtin table across all the targets in Clang. --- clang/include/clang/Basic/BuiltinsARM.def | 7 -- clang/include/clang/Basic/BuiltinsNEON.def | 22 ---- clang/include/clang/Basic/TargetBuiltins.h | 46 +++++--- clang/lib/Basic/Targets/AArch64.cpp | 115 +++++++++++++------- clang/lib/Basic/Targets/ARM.cpp | 88 +++++++++++++--- clang/lib/Sema/SemaARM.cpp | 16 ++- clang/utils/TableGen/MveEmitter.cpp | 91 ++++++++++++---- clang/utils/TableGen/NeonEmitter.cpp | 56 ++++++---- clang/utils/TableGen/SveEmitter.cpp | 116 +++++++++++++++++---- 9 files changed, 387 insertions(+), 170 deletions(-) delete mode 100644 clang/include/clang/Basic/BuiltinsNEON.def 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/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/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 861be58c67336..23463cb20fb3e 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, }; } diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 38238840e52f8..049b8d6b54ca1 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -26,35 +26,80 @@ using namespace clang; using namespace clang::targets; -static constexpr int NumNEONBuiltins = - NEON::FirstTSBuiltin - Builtin::FirstTSBuiltin; +static constexpr int NumNeonBuiltins = + NEON::FirstFp16Builtin - Builtin::FirstTSBuiltin; +static constexpr int NumFp16Builtins = + NEON::FirstTSBuiltin - NEON::FirstFp16Builtin; static constexpr int NumSVEBuiltins = - SVE::FirstTSBuiltin - NEON::FirstTSBuiltin; + 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 + NumSVEBuiltins + - NumSMEBuiltins + NumAArch64Builtins)); +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 +}; -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" - ; -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" - ; -static constexpr llvm::StringTable BuiltinSMEStrings = +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 BUILTIN CLANG_BUILTIN_STR_TABLE #define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE -#include "clang/Basic/BuiltinsSME.def" +#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 @@ -64,21 +109,14 @@ static constexpr llvm::StringTable BuiltinAArch64Strings = #include "clang/Basic/BuiltinsAArch64.def" ; -static constexpr auto BuiltinNEONInfos = Builtin::MakeInfos({ -#define BUILTIN CLANG_BUILTIN_ENTRY +static constexpr auto BuiltinSVENeonBridgeInfos = + Builtin::MakeInfos({ #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" -}); +#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 @@ -732,9 +770,12 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, llvm::SmallVector AArch64TargetInfo::getTargetBuiltins() const { return { - {&BuiltinNEONStrings, BuiltinNEONInfos}, - {&BuiltinSVEStrings, BuiltinSVEInfos}, - {&BuiltinSMEStrings, BuiltinSMEInfos}, + {&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}, }; } diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp index 2b1ab92c22ca0..637ee1cb9cf60 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -1074,26 +1074,81 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, } } -static constexpr int NumBuiltins = - clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin; +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 + +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 -#include "clang/Basic/BuiltinsNEON.def" - #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 LIBBUILTIN CLANG_LIBBUILTIN_ENTRY -#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY -#include "clang/Basic/BuiltinsNEON.def" +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ #define BUILTIN CLANG_BUILTIN_ENTRY #define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY #define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY @@ -1104,7 +1159,14 @@ static constexpr auto BuiltinInfos = Builtin::MakeInfos({ llvm::SmallVector ARMTargetInfo::getTargetBuiltins() const { - return {{&BuiltinStrings, BuiltinInfos}}; + 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/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/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/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) { From 629e5b50f6fab1adae09bcbc80387a5adb346078 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Tue, 17 Dec 2024 19:21:27 +0000 Subject: [PATCH 4/6] [StrTable] Teach main builtin TableGen to use direct enums, strings, and info This moves the main builtins and several targets to use nice generated string tables and info structures rather than X-macros. Even without obvious prefixes factored out, the resulting tables are significantly smaller and much cheaper to compile with out all the X-macro overhead. This leaves the X-macros in place for atomic builtins which have a wide range of uses that don't seem reasonable to fold into TableGen. As future work, these should move to their own file (whether as X-macros or just generated patterns) so the AST headers don't have to include all the data for other builtins. --- clang/include/clang/AST/Expr.h | 2 - clang/include/clang/Basic/Builtins.h | 11 +- clang/include/clang/Basic/IdentifierTable.h | 3 +- clang/include/clang/Basic/TargetBuiltins.h | 23 +- clang/lib/AST/StmtPrinter.cpp | 1 - clang/lib/Basic/Builtins.cpp | 26 +- clang/lib/Basic/Targets/BPF.cpp | 14 +- clang/lib/Basic/Targets/Hexagon.cpp | 17 +- clang/lib/Basic/Targets/NVPTX.cpp | 14 +- clang/lib/Basic/Targets/RISCV.cpp | 16 +- clang/lib/Basic/Targets/SPIR.cpp | 14 +- clang/lib/Basic/Targets/X86.cpp | 51 ++- clang/lib/Sema/SemaChecking.cpp | 1 - .../target-builtins-prototype-parser.td | 18 +- clang/utils/TableGen/ClangBuiltinsEmitter.cpp | 341 +++++++++++------- 15 files changed, 313 insertions(+), 239 deletions(-) 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 ba9108dfe7fce..6d29b4315e5a7 100644 --- a/clang/include/clang/Basic/Builtins.h +++ b/clang/include/clang/Basic/Builtins.h @@ -64,9 +64,10 @@ 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 }; @@ -77,9 +78,9 @@ struct Info { // 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; + llvm::StringTable::Offset Name = {}; + llvm::StringTable::Offset Type = {}; + llvm::StringTable::Offset Attributes = {}; // Defaults to the empty string offset. llvm::StringTable::Offset Features = {}; 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 23463cb20fb3e..4781054240b5b 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -103,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 }; } @@ -123,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 }; } @@ -143,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 @@ -153,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 }; } @@ -192,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 @@ -388,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/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 e5b0ff5361130..e7829a461bbc5 100644 --- a/clang/lib/Basic/Builtins.cpp +++ b/clang/lib/Basic/Builtins.cpp @@ -29,23 +29,19 @@ const char *HeaderDesc::getName() const { llvm_unreachable("Unknown HeaderDesc::HeaderID enum"); } -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 +static constexpr unsigned NumBuiltins = Builtin::FirstTSBuiltin; + +#define GET_BUILTIN_STR_TABLE #include "clang/Basic/Builtins.inc" - ; -static_assert(BuiltinStrings.size() < 100'000); - -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 +#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); std::pair Builtin::Context::getShardAndInfo(unsigned ID) const { diff --git a/clang/lib/Basic/Targets/BPF.cpp b/clang/lib/Basic/Targets/BPF.cpp index b4504faa4d5ee..a463de0884020 100644 --- a/clang/lib/Basic/Targets/BPF.cpp +++ b/clang/lib/Basic/Targets/BPF.cpp @@ -22,16 +22,16 @@ using namespace clang::targets; 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 +#define GET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsBPF.inc" - ; +#undef GET_BUILTIN_STR_TABLE -static constexpr auto BuiltinInfos = Builtin::MakeInfos({ -#define BUILTIN CLANG_BUILTIN_ENTRY +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 { diff --git a/clang/lib/Basic/Targets/Hexagon.cpp b/clang/lib/Basic/Targets/Hexagon.cpp index acf44efb76e55..c73ecee53ed1b 100644 --- a/clang/lib/Basic/Targets/Hexagon.cpp +++ b/clang/lib/Basic/Targets/Hexagon.cpp @@ -207,19 +207,16 @@ ArrayRef HexagonTargetInfo::getGCCRegAliases() const { 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 +#define GET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsHexagon.inc" - ; +#undef GET_BUILTIN_STR_TABLE -static constexpr auto BuiltinInfos = Builtin::MakeInfos({ -#define BUILTIN CLANG_BUILTIN_ENTRY -#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY -#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS #include "clang/Basic/BuiltinsHexagon.inc" -}); +#undef GET_BUILTIN_INFOS +}; +static_assert(std::size(BuiltinInfos) == NumBuiltins); bool HexagonTargetInfo::hasFeature(StringRef Feature) const { std::string VS = "hvxv" + HVXVersion; diff --git a/clang/lib/Basic/Targets/NVPTX.cpp b/clang/lib/Basic/Targets/NVPTX.cpp index 9d2d517bc7226..1fbb7bbe33769 100644 --- a/clang/lib/Basic/Targets/NVPTX.cpp +++ b/clang/lib/Basic/Targets/NVPTX.cpp @@ -23,16 +23,16 @@ using namespace clang::targets; 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 +#define GET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsNVPTX.inc" - ; +#undef GET_BUILTIN_STR_TABLE -static constexpr auto BuiltinInfos = Builtin::MakeInfos({ -#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +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"}; diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index c4317a10d25aa..b4aa3206fcfab 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -277,18 +277,16 @@ static constexpr std::array BuiltinInfos = }; } // namespace RVVSiFive -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 GET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsRISCV.inc" - ; +#undef GET_BUILTIN_STR_TABLE -static constexpr auto BuiltinInfos = Builtin::MakeInfos({ -#define BUILTIN CLANG_BUILTIN_ENTRY -#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +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 { diff --git a/clang/lib/Basic/Targets/SPIR.cpp b/clang/lib/Basic/Targets/SPIR.cpp index a242fd8c4b5c8..5c076f694dfa4 100644 --- a/clang/lib/Basic/Targets/SPIR.cpp +++ b/clang/lib/Basic/Targets/SPIR.cpp @@ -23,16 +23,16 @@ using namespace clang::targets; static constexpr int NumBuiltins = clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin; -static constexpr llvm::StringTable BuiltinStrings = - CLANG_BUILTIN_STR_TABLE_START -#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define GET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsSPIRV.inc" - ; +#undef GET_BUILTIN_STR_TABLE -static constexpr auto BuiltinInfos = Builtin::MakeInfos({ -#define BUILTIN CLANG_BUILTIN_ENTRY +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS #include "clang/Basic/BuiltinsSPIRV.inc" -}); +#undef GET_BUILTIN_INFOS +}; +static_assert(std::size(BuiltinInfos) == NumBuiltins); llvm::SmallVector SPIRVTargetInfo::getTargetBuiltins() const { diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index 1bb5f78eef712..79b3bdadce15e 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -31,36 +31,31 @@ static constexpr int NumX86_64Builtins = static constexpr int NumBuiltins = X86::LastTSBuiltin - Builtin::FirstTSBuiltin; static_assert(NumBuiltins == (NumX86Builtins + NumX86_64Builtins)); -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 +namespace X86 { +#define GET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsX86.inc" - ; +#undef GET_BUILTIN_STR_TABLE -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 +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS #include "clang/Basic/BuiltinsX86.inc" -}); +#undef GET_BUILTIN_INFOS +}; +static_assert(std::size(BuiltinInfos) == NumX86Builtins); +} // namespace X86 -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 +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_assert(std::size(BuiltinInfos) == NumX86_64Builtins); +} // namespace X86_64 static const char *const GCCRegNames[] = { "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", @@ -1879,13 +1874,13 @@ ArrayRef X86TargetInfo::getGCCAddlRegNames() const { llvm::SmallVector X86_32TargetInfo::getTargetBuiltins() const { - return {{&BuiltinX86Strings, BuiltinX86Infos}}; + return {{&X86::BuiltinStrings, X86::BuiltinInfos}}; } llvm::SmallVector X86_64TargetInfo::getTargetBuiltins() const { return { - {&BuiltinX86Strings, BuiltinX86Infos}, - {&BuiltinX86_64Strings, BuiltinX86_64Infos}, + {&X86::BuiltinStrings, X86::BuiltinInfos}, + {&X86_64::BuiltinStrings, X86_64::BuiltinInfos}, }; } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index b345e40a328b5..66c233de4ef30 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2451,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); 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..e6c74902bb482 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,119 @@ 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" << 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 +152,8 @@ class PrototypeParser { ParsePrototype(Builtin->getValueAsString("Prototype")); } + std::string takeTypeString() && { return std::move(Type); } + private: void ParsePrototype(StringRef Prototype) { Prototype = Prototype.trim(); @@ -243,37 +360,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 +397,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 +434,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 +446,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 +476,77 @@ 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); - // AtomicBuiltins are order dependent - // emit them first to make manual checking easier - for (const auto *Builtin : Records.getAllDerivedDefinitions("AtomicBuiltin")) - EmitBuiltin(OS, Builtin); + unsigned NumAtomicBuiltins = Builtins.size(); - for (const auto *Builtin : Records.getAllDerivedDefinitions("Builtin")) { - if (Builtin->isSubClassOf("AtomicBuiltin")) + for (const auto *BuiltinRecord : + Records.getAllDerivedDefinitions("Builtin")) { + if (BuiltinRecord->isSubClassOf("AtomicBuiltin")) continue; - EmitBuiltin(OS, Builtin); + collectBuiltins(BuiltinRecord, Builtins); + } + + auto AtomicBuiltins = ArrayRef(Builtins).slice(0, NumAtomicBuiltins); + + // 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. + OS << R"c++( +#ifdef GET_BUILTIN_INFOS +)c++"; + for (const auto &B : Builtins) + B.EmitInfo(OS, Table); + OS << R"c++( +#endif // GET_BUILTIN_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++"; } From 7529707b8d4b1c60133eae437711189f2f1448b3 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sun, 5 Jan 2025 15:01:37 +0000 Subject: [PATCH 5/6] [StrTable] Add prefixes for x86 builtins. This requires adding support to the general builtins emission for producing prefixed builtin infos separately from un-prefixed which is a bit crufty. But we don't currently have any good way of having a more refined model than a single hard-coded prefix string per TableGen emission. Something more powerful and/or elegant is possible, but this is a fairly minimal first step that at least allows factoring out the builtin prefix for something like X86. --- clang/include/clang/Basic/BuiltinsBase.td | 10 ++++ clang/include/clang/Basic/BuiltinsX86Base.td | 5 +- clang/lib/Basic/Targets/X86.cpp | 26 ++++++++-- clang/utils/TableGen/ClangBuiltinsEmitter.cpp | 49 +++++++++++++++++-- 4 files changed, 82 insertions(+), 8 deletions(-) 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/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/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index 79b3bdadce15e..84a05cec04e7f 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -41,7 +41,14 @@ static constexpr Builtin::Info BuiltinInfos[] = { #include "clang/Basic/BuiltinsX86.inc" #undef GET_BUILTIN_INFOS }; -static_assert(std::size(BuiltinInfos) == NumX86Builtins); + +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 { @@ -54,7 +61,14 @@ static constexpr Builtin::Info BuiltinInfos[] = { #include "clang/Basic/BuiltinsX86_64.inc" #undef GET_BUILTIN_INFOS }; -static_assert(std::size(BuiltinInfos) == NumX86_64Builtins); + +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[] = { @@ -1874,13 +1888,19 @@ ArrayRef X86TargetInfo::getGCCAddlRegNames() const { llvm::SmallVector X86_32TargetInfo::getTargetBuiltins() const { - return {{&X86::BuiltinStrings, X86::BuiltinInfos}}; + return { + {&X86::BuiltinStrings, X86::BuiltinInfos}, + {&X86::BuiltinStrings, X86::PrefixedBuiltinInfos, "__builtin_ia32_"}, + }; } 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/utils/TableGen/ClangBuiltinsEmitter.cpp b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp index e6c74902bb482..352765acf5338 100644 --- a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp +++ b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp @@ -59,7 +59,13 @@ struct Builtin { const Record *BuiltinRecord; void EmitEnumerator(llvm::raw_ostream &OS) const { - OS << " BI" << Name << ",\n"; + 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 { @@ -482,17 +488,42 @@ void clang::EmitClangBuiltins(const RecordKeeper &Records, raw_ostream &OS) { 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; + collectBuiltins(BuiltinRecord, Builtins); } + // 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; + + 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; @@ -524,14 +555,24 @@ void clang::EmitClangBuiltins(const RecordKeeper &Records, raw_ostream &OS) { #endif // GET_BUILTIN_STR_TABLE )c++"; - // Emit a direct set of `Builtin::Info` initializers. + // 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 : Builtins) + 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 From 6bedde20d9b0d73cafc842612631a39af95bcd2d Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 18 Jan 2025 12:32:07 +0000 Subject: [PATCH 6/6] [StrTable] Add factored prefix for Hexagon This target's builtins have an especially long prefix and so we get over 2x reduction in string table size required with this change. --- clang/include/clang/Basic/BuiltinsHexagon.td | 5 ++++- clang/lib/Basic/Targets/Hexagon.cpp | 12 ++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) 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/lib/Basic/Targets/Hexagon.cpp b/clang/lib/Basic/Targets/Hexagon.cpp index c73ecee53ed1b..c19c2e76c511a 100644 --- a/clang/lib/Basic/Targets/Hexagon.cpp +++ b/clang/lib/Basic/Targets/Hexagon.cpp @@ -216,7 +216,14 @@ static constexpr Builtin::Info BuiltinInfos[] = { #include "clang/Basic/BuiltinsHexagon.inc" #undef GET_BUILTIN_INFOS }; -static_assert(std::size(BuiltinInfos) == NumBuiltins); + +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; @@ -277,5 +284,6 @@ void HexagonTargetInfo::fillValidCPUList( llvm::SmallVector HexagonTargetInfo::getTargetBuiltins() const { - return {{&BuiltinStrings, BuiltinInfos}}; + return {{&BuiltinStrings, BuiltinInfos}, + {&BuiltinStrings, PrefixedBuiltinInfos, "__builtin_HEXAGON_"}}; }