[clang] Patch series to reapply #118734 and substantially improve it (PR #120534)
Chandler Carruth via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 3 21:56:28 PST 2025
https://github.com/chandlerc updated https://github.com/llvm/llvm-project/pull/120534
>From b4b330f465924695a8fddfd51c4f055774fef9fb Mon Sep 17 00:00:00 2001
From: Chandler Carruth <chandlerc at gmail.com>
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 63559d977ce6b6..ba9108dfe7fce5 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 <cstring>
// 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 <size_t N>
+static constexpr std::array<Info, N> MakeInfos(std::array<Info, N> 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<Info> 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<Info> TSRecords;
- llvm::ArrayRef<Info> AuxTSRecords;
+ llvm::SmallVector<InfosShard> BuiltinShards;
+
+ llvm::SmallVector<InfosShard> TargetShards;
+ llvm::SmallVector<InfosShard> 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<const InfosShard &, const Info &>
+ 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 95359a3fdc711d..00000000000000
--- 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 161df386f00f03..bb7d54bbb793eb 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 95eb110bb9c246..2a9f9a7dd422d3 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 d762144478b489..77c2f88a172d99 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<Builtin::Info> 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<Builtin::InfosShard> getTargetBuiltins() const = 0;
/// Returns target-specific min and max values VScale_Range.
virtual std::optional<std::pair<unsigned, unsigned>>
diff --git a/clang/include/module.modulemap b/clang/include/module.modulemap
index b318bd95ee67c3..e2bc941d3143a6 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 588183788de322..e5b0ff53611309 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<Builtin::FirstTSBuiltin>(
+ {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<const Builtin::InfosShard &, const Builtin::Info &>
+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<InfosShard> 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<int> &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 57c9849ef2a728..38238840e52f81 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<NumNEONBuiltins>({
+#define BUILTIN CLANG_BUILTIN_ENTRY
+#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
+#include "clang/Basic/BuiltinsNEON.def"
+});
+static constexpr auto BuiltinSVEInfos = Builtin::MakeInfos<NumSVEBuiltins>({
+#define BUILTIN CLANG_BUILTIN_ENTRY
+#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
+#include "clang/Basic/BuiltinsSVE.def"
+});
+static constexpr auto BuiltinSMEInfos = Builtin::MakeInfos<NumSMEBuiltins>({
+#define BUILTIN CLANG_BUILTIN_ENTRY
+#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
+#include "clang/Basic/BuiltinsSME.def"
+});
+static constexpr auto BuiltinAArch64Infos =
+ Builtin::MakeInfos<NumAArch64Builtins>({
+#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<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+AArch64TargetInfo::getTargetBuiltins() const {
+ return {
+ {&BuiltinNEONStrings, BuiltinNEONInfos},
+ {&BuiltinSVEStrings, BuiltinSVEInfos},
+ {&BuiltinSMEStrings, BuiltinSMEInfos},
+ {&BuiltinAArch64Strings, BuiltinAArch64Infos},
+ };
}
std::optional<std::pair<unsigned, unsigned>>
diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h
index 79e012f48e65b7..f2510adb0ea225 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
std::optional<std::pair<unsigned, unsigned>>
getVScaleRange(const LangOptions &LangOpts,
diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp
index 0d308cb6af9699..228f967caf2f1a 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<NumBuiltins>({
+#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<Builtin::Info> AMDGPUTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo,
- clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+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 ea4189cdea47da..3d6778fb5a76fb 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<std::string> &FeatureVec) const override;
- ArrayRef<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 7f3d0aa15ab81f..2b69f95591fa10 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<Builtin::Info> getTargetBuiltins() const override { return {}; }
+ llvm::SmallVector<Builtin::InfosShard> 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 5aa2baeb81b731..2b1ab92c22ca0c 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<NumBuiltins>({
+#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<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo,
- clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+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 5f4acce7af5a46..22033a6da33891 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 df1f8d171efbaa..2117ab58e6f303 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<Builtin::Info> getTargetBuiltins() const override { return {}; }
+ llvm::SmallVector<Builtin::InfosShard> 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 f4684765b7ffb3..b4504faa4d5eeb 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<NumBuiltins>({
+#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<StringRef> &Values) const {
Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
}
-ArrayRef<Builtin::Info> BPFTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo,
- clang::BPF::LastTSBuiltin - Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+BPFTargetInfo::getTargetBuiltins() const {
+ return {{&BuiltinStrings, BuiltinInfos}};
}
bool BPFTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
diff --git a/clang/lib/Basic/Targets/BPF.h b/clang/lib/Basic/Targets/BPF.h
index 27a4b5f3149702..d1f68b842348ea 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<std::string> &Features,
DiagnosticsEngine &Diags) override;
- ArrayRef<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 c8bf8b9234d243..e698508a2370c9 100644
--- a/clang/lib/Basic/Targets/CSKY.cpp
+++ b/clang/lib/Basic/Targets/CSKY.cpp
@@ -139,10 +139,6 @@ bool CSKYTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
return true;
}
-ArrayRef<Builtin::Info> CSKYTargetInfo::getTargetBuiltins() const {
- return ArrayRef<Builtin::Info>();
-}
-
ArrayRef<const char *> CSKYTargetInfo::getGCCRegNames() const {
static const char *const GCCRegNames[] = {
// Integer registers
diff --git a/clang/lib/Basic/Targets/CSKY.h b/clang/lib/Basic/Targets/CSKY.h
index 94d4eeb9a1fff4..ddfbe4794daadd 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 4e6bc0e040398b..6e3ddad6263416 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<Builtin::Info> getTargetBuiltins() const override { return {}; }
+ llvm::SmallVector<Builtin::InfosShard> 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 2e173e01ed8ed6..acf44efb76e559 100644
--- a/clang/lib/Basic/Targets/Hexagon.cpp
+++ b/clang/lib/Basic/Targets/Hexagon.cpp
@@ -204,15 +204,22 @@ ArrayRef<TargetInfo::GCCRegAlias> 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<NumBuiltins>({
+#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<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+HexagonTargetInfo::getTargetBuiltins() const {
+ return {{&BuiltinStrings, BuiltinInfos}};
}
diff --git a/clang/lib/Basic/Targets/Hexagon.h b/clang/lib/Basic/Targets/Hexagon.h
index 7f053ab7e48886..a65663ca09eee7 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 f7e439c7c9e1cf..e32ef9d7d40daa 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<Builtin::Info> getTargetBuiltins() const override { return {}; }
+ llvm::SmallVector<Builtin::InfosShard> 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 bb0d0b68cfcb0a..ca742797d7a3bf 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<NumBaseBuiltins>({
+#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<NumLSXBuiltins>({
+#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<NumLASXBuiltins>({
+#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
+#include "clang/Basic/BuiltinsLoongArchLASX.def"
+#undef TARGET_BUILTIN
+});
bool LoongArchTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
@@ -306,9 +348,13 @@ bool LoongArchTargetInfo::hasFeature(StringRef Feature) const {
.Default(false);
}
-ArrayRef<Builtin::Info> LoongArchTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo, clang::LoongArch::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+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 5c34c84ff8d3e8..4c7b53abfef9b4 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 b5b29fd8675630..e5b7f06829cd91 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<Builtin::Info> M68kTargetInfo::getTargetBuiltins() const {
+llvm::SmallVector<Builtin::InfosShard>
+M68kTargetInfo::getTargetBuiltins() const {
// FIXME: Implement.
return {};
}
diff --git a/clang/lib/Basic/Targets/M68k.h b/clang/lib/Basic/Targets/M68k.h
index b732add77e0340..729d79ff77fbf6 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
bool hasFeature(StringRef Feature) const override;
ArrayRef<const char *> getGCCRegNames() const override;
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
diff --git a/clang/lib/Basic/Targets/MSP430.h b/clang/lib/Basic/Targets/MSP430.h
index 2266ada25c1dd6..d7d05f992f4f6b 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<Builtin::Info> getTargetBuiltins() const override {
+ llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override {
// FIXME: Implement.
return {};
}
diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp
index d56995e3ccc48e..866be53c8a3632 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<NumBuiltins>({
+#define BUILTIN CLANG_BUILTIN_ENTRY
+#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
#include "clang/Basic/BuiltinsMips.def"
-};
+});
bool MipsTargetInfo::processorSupportsGPR64() const {
return llvm::StringSwitch<bool>(CPU)
@@ -223,9 +230,9 @@ bool MipsTargetInfo::hasFeature(StringRef Feature) const {
.Default(false);
}
-ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo,
- clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+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 7ddcd57053cb2b..35501ed44ccd72 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 a03f4983b9d038..9d2d517bc72266 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<NumBuiltins>({
+#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<Builtin::Info> NVPTXTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo,
- clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+NVPTXTargetInfo::getTargetBuiltins() const {
+ return {{&BuiltinStrings, BuiltinInfos}};
}
diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index c6531148fe30ce..6a868c42e12651 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 7e0e10aa362d87..d162776b5a0d63 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<Builtin::Info> getTargetBuiltins() const override { return {}; }
+ llvm::SmallVector<Builtin::InfosShard> 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 1448069173b5f4..2d8891a739ca35 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<NumBuiltins>({
+#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<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo,
- clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+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 3cd0fcad172939..db6ac6f0bd3380 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 61b8ae9d098abc..a63796d2f5a1e6 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<Builtin::Info> RISCVTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo,
- clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin);
+static constexpr auto BuiltinRVVInfos = Builtin::MakeInfos<NumRVVBuiltins>({
+#define BUILTIN CLANG_BUILTIN_ENTRY
+#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
+#include "clang/Basic/BuiltinsRISCVVector.def"
+});
+static constexpr auto BuiltinRISCVInfos = Builtin::MakeInfos<NumRISCVBuiltins>({
+#define BUILTIN CLANG_BUILTIN_ENTRY
+#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
+#include "clang/Basic/BuiltinsRISCV.inc"
+});
+
+llvm::SmallVector<Builtin::InfosShard>
+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 d31c46f2bb16c0..c26aa190801626 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 f242fedc1ad661..a242fd8c4b5c8a 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<NumBuiltins>({
+#define BUILTIN CLANG_BUILTIN_ENTRY
#include "clang/Basic/BuiltinsSPIRV.inc"
-};
+});
-ArrayRef<Builtin::Info> SPIRVTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo,
- clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+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<Builtin::Info> SPIRV64AMDGCNTargetInfo::getTargetBuiltins() const {
+llvm::SmallVector<Builtin::InfosShard>
+SPIRV64AMDGCNTargetInfo::getTargetBuiltins() const {
return AMDGPUTI.getTargetBuiltins();
}
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index c0849b69dcdb32..61f9ef7e3e3611 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<Builtin::Info> getTargetBuiltins() const override { return {}; }
+ llvm::SmallVector<Builtin::InfosShard> 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<Builtin::Info> getTargetBuiltins() const override;
+
+ llvm::SmallVector<Builtin::InfosShard> 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 9c529a5bc5e7fa..3215e648ba6c31 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<Builtin::Info> getTargetBuiltins() const override {
+ llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override {
// FIXME: Implement!
return {};
}
diff --git a/clang/lib/Basic/Targets/SystemZ.cpp b/clang/lib/Basic/Targets/SystemZ.cpp
index c836d110d26d5f..0e9a61c6a01c89 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<NumBuiltins>({
+#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<Builtin::Info> SystemZTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo, clang::SystemZ::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+SystemZTargetInfo::getTargetBuiltins() const {
+ return {{&BuiltinStrings, BuiltinInfos}};
}
diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h
index bd2827cf13a5ba..4ca3f53f83cba0 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
ArrayRef<const char *> getGCCRegNames() const override;
diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h
index edec30bf69de0c..46c70de8f9ec16 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<Builtin::Info> getTargetBuiltins() const override { return {}; }
+ llvm::SmallVector<Builtin::InfosShard> 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 67cae8faf60522..5451f3c303637d 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<NumBuiltins>({
+#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<Builtin::Info> VETargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo,
- clang::VE::LastTSBuiltin - Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard> VETargetInfo::getTargetBuiltins() const {
+ return {{&BuiltinStrings, BuiltinInfos}};
}
diff --git a/clang/lib/Basic/Targets/VE.h b/clang/lib/Basic/Targets/VE.h
index 7e8fdf6096ef23..e9b7e92f3f8504 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 7b0fd0c841ba23..f19c57f1a3a502 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<NumBuiltins>({
+#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<Builtin::Info> WebAssemblyTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+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 cfecc59ac75fd9..fb48c786a7edb8 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<Builtin::Info> getTargetBuiltins() const final;
+ llvm::SmallVector<Builtin::InfosShard> 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 40ad8fd9a0967d..1bb5f78eef7121 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<NumX86Builtins>({
+#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<NumX86_64Builtins>({
+#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<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
return llvm::ArrayRef(AddlRegNames);
}
-ArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin -
- Builtin::FirstTSBuiltin + 1);
+llvm::SmallVector<Builtin::InfosShard>
+X86_32TargetInfo::getTargetBuiltins() const {
+ return {{&BuiltinX86Strings, BuiltinX86Infos}};
}
-ArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfoX86,
- X86::LastTSBuiltin - Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+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 8bd54e362526fb..205edcab9ccb37 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 fd377bbfb90e16..c725703ede5b0b 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<NumBuiltins>({
+#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<Builtin::Info> XCoreTargetInfo::getTargetBuiltins() const {
- return llvm::ArrayRef(BuiltinInfo,
- clang::XCore::LastTSBuiltin - Builtin::FirstTSBuiltin);
+llvm::SmallVector<Builtin::InfosShard>
+XCoreTargetInfo::getTargetBuiltins() const {
+ return {{&BuiltinStrings, BuiltinInfos}};
}
diff --git a/clang/lib/Basic/Targets/XCore.h b/clang/lib/Basic/Targets/XCore.h
index 84fd59d1a71e49..9af9e0658f629a 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<Builtin::Info> getTargetBuiltins() const override;
+ llvm::SmallVector<Builtin::InfosShard> 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 a440ba8aa3c6d6..470835aacff527 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<Builtin::Info> getTargetBuiltins() const override {
- return std::nullopt;
+ llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override {
+ return {};
}
BuiltinVaListKind getBuiltinVaListKind() const override {
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 4d3d9e9897c148..96e1e0dc111817 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 82002b8d8e4d4f..02615bb13dfb8a 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 61b2c8cf1cad72..b345e40a328b53 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 ba4aaa94b90ffd..3cd4010740d194 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 96464b30c078f4..d0145293fa3e52 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 <chandlerc at gmail.com>
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 6dfa87a1a1d313..00000000000000
--- 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 2a9f9a7dd422d3..861be58c673368 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 a63796d2f5a1e6..c4317a10d25aaa 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<Builtin::Info, NumRVVBuiltins> 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<Builtin::Info, NumRVVSiFiveBuiltins> 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<NumRVVBuiltins>({
-#define BUILTIN CLANG_BUILTIN_ENTRY
-#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
-#include "clang/Basic/BuiltinsRISCVVector.def"
-});
-static constexpr auto BuiltinRISCVInfos = Builtin::MakeInfos<NumRISCVBuiltins>({
+static constexpr auto BuiltinInfos = Builtin::MakeInfos<NumRISCVBuiltins>({
#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<NumRISCVBuiltins>({
llvm::SmallVector<Builtin::InfosShard>
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 acba1a31912816..0cdde20060b63b 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 <optional>
using namespace llvm;
@@ -498,31 +500,68 @@ void RVVEmitter::createBuiltins(raw_ostream &OS) {
std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
createRVVIntrinsics(Defs);
- // Map to keep track of which builtin names have already been emitted.
- StringMap<RVVIntrinsic *> 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<RVVIntrinsic *> BuiltinMap;
+ std::vector<RVVIntrinsic *> 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 <chandlerc at gmail.com>
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 5a7064a98045e7..cbab87cecbc7d7 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 9627005ba9824e..00000000000000
--- 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 861be58c673368..23463cb20fb3eb 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 38238840e52f81..049b8d6b54ca10 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<Builtin::Info, NumNeonBuiltins> 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<Builtin::Info, NumFp16Builtins> 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<Builtin::Info, NumSVEBuiltins> 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<Builtin::Info, NumSMEBuiltins> 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<NumNEONBuiltins>({
-#define BUILTIN CLANG_BUILTIN_ENTRY
+static constexpr auto BuiltinSVENeonBridgeInfos =
+ Builtin::MakeInfos<NumSVENeonBridgeBuiltins>({
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
-#include "clang/Basic/BuiltinsNEON.def"
-});
-static constexpr auto BuiltinSVEInfos = Builtin::MakeInfos<NumSVEBuiltins>({
-#define BUILTIN CLANG_BUILTIN_ENTRY
-#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
-#include "clang/Basic/BuiltinsSVE.def"
-});
-static constexpr auto BuiltinSMEInfos = Builtin::MakeInfos<NumSMEBuiltins>({
-#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<NumAArch64Builtins>({
#define BUILTIN CLANG_BUILTIN_ENTRY
@@ -732,9 +770,12 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
llvm::SmallVector<Builtin::InfosShard>
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 2b1ab92c22ca0c..637ee1cb9cf607 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<Builtin::Info, NumNeonBuiltins> 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<Builtin::Info, NumFp16Builtins> 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<Builtin::Info, NumMVEBuiltins> 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<Builtin::Info, NumCDEBuiltins> 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<NumBuiltins>({
-#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<NumARMBuiltins>({
#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<NumBuiltins>({
llvm::SmallVector<Builtin::InfosShard>
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 71dfe68f104ed9..b4b40f293b28e7 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<ArmStreamingType> 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 58a4d3c22ac366..e77679876a3af5 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<std::string, ACLEIntrinsic *> 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<StringRef> 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 295e7eb89c967f..a18f78697af1c1 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 <algorithm>
#include <cassert>
#include <cctype>
@@ -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<Intrinsic *> &Defs) {
- OS << "#ifdef GET_NEON_BUILTINS\n";
+ // We only want to emit a builtin once, and in order of its name.
+ std::map<std::string, Intrinsic *> 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<std::pair<std::string, std::string>> 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 39dcbc678dc486..e226987b4844bf 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 <array>
#include <cctype>
#include <set>
@@ -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<std::pair<std::string, std::string>> ReinterpretBuiltins;
for (auto [N, Suffix] :
std::initializer_list<std::pair<unsigned, const char *>>{
{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 <chandlerc at gmail.com>
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 7be4022649329b..cd584d9621a226 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 ba9108dfe7fce5..6d29b4315e5a77 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 e5e6be3c966003..0347880244a407 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 23463cb20fb3eb..4781054240b5bb 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 bae4134e283594..3ce932a9dd352c 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 e5b0ff53611309..e7829a461bbc53 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<Builtin::FirstTSBuiltin>(
- {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<const Builtin::InfosShard &, const Builtin::Info &>
Builtin::Context::getShardAndInfo(unsigned ID) const {
diff --git a/clang/lib/Basic/Targets/BPF.cpp b/clang/lib/Basic/Targets/BPF.cpp
index b4504faa4d5eeb..a463de08840201 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<NumBuiltins>({
-#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 acf44efb76e559..c73ecee53ed1b6 100644
--- a/clang/lib/Basic/Targets/Hexagon.cpp
+++ b/clang/lib/Basic/Targets/Hexagon.cpp
@@ -207,19 +207,16 @@ ArrayRef<TargetInfo::GCCRegAlias> 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<NumBuiltins>({
-#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 9d2d517bc72266..1fbb7bbe33769c 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<NumBuiltins>({
-#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 c4317a10d25aaa..b4aa3206fcfabf 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -277,18 +277,16 @@ static constexpr std::array<Builtin::Info, NumRVVSiFiveBuiltins> 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<NumRISCVBuiltins>({
-#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<Builtin::InfosShard>
RISCVTargetInfo::getTargetBuiltins() const {
diff --git a/clang/lib/Basic/Targets/SPIR.cpp b/clang/lib/Basic/Targets/SPIR.cpp
index a242fd8c4b5c8a..5c076f694dfa4d 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<NumBuiltins>({
-#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<Builtin::InfosShard>
SPIRVTargetInfo::getTargetBuiltins() const {
diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index 1bb5f78eef7121..79b3bdadce15e6 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<NumX86Builtins>({
-#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<NumX86_64Builtins>({
-#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<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
llvm::SmallVector<Builtin::InfosShard>
X86_32TargetInfo::getTargetBuiltins() const {
- return {{&BuiltinX86Strings, BuiltinX86Infos}};
+ return {{&X86::BuiltinStrings, X86::BuiltinInfos}};
}
llvm::SmallVector<Builtin::InfosShard>
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 b345e40a328b53..66c233de4ef30b 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 a753f906a674fe..451f1a18b8ad06 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 5c5f011cd940eb..e6c74902bb482a 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 <sstream>
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<char>(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<char>(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<Builtin> &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<Builtin> 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 <chandlerc at gmail.com>
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 6180a94aa4b5c7..cf15a31235e7ea 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<list<int> ArgIndices> : MultiIndexAttribute<"C", ArgIndices>;
+// Prefixes
+// ========
+
+class NamePrefix<string spelling> {
+ 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 aca39c204516ae..0d739ee0b0b69e 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<string prototype> : 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<string prototype> : TargetBuiltin {
diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index 79b3bdadce15e6..84a05cec04e7f5 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<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
llvm::SmallVector<Builtin::InfosShard>
X86_32TargetInfo::getTargetBuiltins() const {
- return {{&X86::BuiltinStrings, X86::BuiltinInfos}};
+ return {
+ {&X86::BuiltinStrings, X86::BuiltinInfos},
+ {&X86::BuiltinStrings, X86::PrefixedBuiltinInfos, "__builtin_ia32_"},
+ };
}
llvm::SmallVector<Builtin::InfosShard>
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 e6c74902bb482a..352765acf53380 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 <chandlerc at gmail.com>
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 95b9012bf74f90..0727c67346697f 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<string prototype> : 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<string prototype> : TargetBuiltin {
diff --git a/clang/lib/Basic/Targets/Hexagon.cpp b/clang/lib/Basic/Targets/Hexagon.cpp
index c73ecee53ed1b6..c19c2e76c511ac 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<Builtin::InfosShard>
HexagonTargetInfo::getTargetBuiltins() const {
- return {{&BuiltinStrings, BuiltinInfos}};
+ return {{&BuiltinStrings, BuiltinInfos},
+ {&BuiltinStrings, PrefixedBuiltinInfos, "__builtin_HEXAGON_"}};
}
More information about the cfe-commits
mailing list